clang  17.0.0git
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
29 #include "clang/Basic/TargetInfo.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallSet.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Frontend/OpenMP/OMPAssume.h"
41 #include "llvm/Frontend/OpenMP/OMPConstants.h"
42 #include <optional>
43 #include <set>
44 
45 using namespace clang;
46 using namespace llvm::omp;
47 
48 //===----------------------------------------------------------------------===//
49 // Stack of data-sharing attributes for variables
50 //===----------------------------------------------------------------------===//
51 
53  Sema &SemaRef, Expr *E,
55  OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
56 
57 namespace {
58 /// Default data sharing attributes, which can be applied to directive.
59 enum DefaultDataSharingAttributes {
60  DSA_unspecified = 0, /// Data sharing attribute not specified.
61  DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
62  DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
63  DSA_private = 1 << 2, /// Default data sharing attribute 'private'.
64  DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
65 };
66 
67 /// Stack for tracking declarations used in OpenMP directives and
68 /// clauses and their data-sharing attributes.
69 class DSAStackTy {
70 public:
71  struct DSAVarData {
72  OpenMPDirectiveKind DKind = OMPD_unknown;
73  OpenMPClauseKind CKind = OMPC_unknown;
74  unsigned Modifier = 0;
75  const Expr *RefExpr = nullptr;
76  DeclRefExpr *PrivateCopy = nullptr;
77  SourceLocation ImplicitDSALoc;
78  bool AppliedToPointee = false;
79  DSAVarData() = default;
80  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
81  const Expr *RefExpr, DeclRefExpr *PrivateCopy,
82  SourceLocation ImplicitDSALoc, unsigned Modifier,
83  bool AppliedToPointee)
84  : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
85  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
86  AppliedToPointee(AppliedToPointee) {}
87  };
88  using OperatorOffsetTy =
90  using DoacrossDependMapTy =
91  llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
92  /// Kind of the declaration used in the uses_allocators clauses.
93  enum class UsesAllocatorsDeclKind {
94  /// Predefined allocator
95  PredefinedAllocator,
96  /// User-defined allocator
97  UserDefinedAllocator,
98  /// The declaration that represent allocator trait
99  AllocatorTrait,
100  };
101 
102 private:
103  struct DSAInfo {
104  OpenMPClauseKind Attributes = OMPC_unknown;
105  unsigned Modifier = 0;
106  /// Pointer to a reference expression and a flag which shows that the
107  /// variable is marked as lastprivate(true) or not (false).
108  llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
109  DeclRefExpr *PrivateCopy = nullptr;
110  /// true if the attribute is applied to the pointee, not the variable
111  /// itself.
112  bool AppliedToPointee = false;
113  };
114  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
115  using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
116  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
117  using LoopControlVariablesMapTy =
118  llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
119  /// Struct that associates a component with the clause kind where they are
120  /// found.
121  struct MappedExprComponentTy {
123  OpenMPClauseKind Kind = OMPC_unknown;
124  };
125  using MappedExprComponentsTy =
126  llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
127  using CriticalsWithHintsTy =
128  llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
129  struct ReductionData {
130  using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
131  SourceRange ReductionRange;
132  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
133  ReductionData() = default;
134  void set(BinaryOperatorKind BO, SourceRange RR) {
135  ReductionRange = RR;
136  ReductionOp = BO;
137  }
138  void set(const Expr *RefExpr, SourceRange RR) {
139  ReductionRange = RR;
140  ReductionOp = RefExpr;
141  }
142  };
143  using DeclReductionMapTy =
144  llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
145  struct DefaultmapInfo {
146  OpenMPDefaultmapClauseModifier ImplicitBehavior =
148  SourceLocation SLoc;
149  DefaultmapInfo() = default;
150  DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
151  : ImplicitBehavior(M), SLoc(Loc) {}
152  };
153 
154  struct SharingMapTy {
155  DeclSAMapTy SharingMap;
156  DeclReductionMapTy ReductionMap;
157  UsedRefMapTy AlignedMap;
158  UsedRefMapTy NontemporalMap;
159  MappedExprComponentsTy MappedExprComponents;
160  LoopControlVariablesMapTy LCVMap;
161  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
162  SourceLocation DefaultAttrLoc;
163  DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
164  OpenMPDirectiveKind Directive = OMPD_unknown;
165  DeclarationNameInfo DirectiveName;
166  Scope *CurScope = nullptr;
167  DeclContext *Context = nullptr;
168  SourceLocation ConstructLoc;
169  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
170  /// get the data (loop counters etc.) about enclosing loop-based construct.
171  /// This data is required during codegen.
172  DoacrossDependMapTy DoacrossDepends;
173  /// First argument (Expr *) contains optional argument of the
174  /// 'ordered' clause, the second one is true if the regions has 'ordered'
175  /// clause, false otherwise.
176  std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
177  bool RegionHasOrderConcurrent = false;
178  unsigned AssociatedLoops = 1;
179  bool HasMutipleLoops = false;
180  const Decl *PossiblyLoopCounter = nullptr;
181  bool NowaitRegion = false;
182  bool UntiedRegion = false;
183  bool CancelRegion = false;
184  bool LoopStart = false;
185  bool BodyComplete = false;
186  SourceLocation PrevScanLocation;
187  SourceLocation PrevOrderedLocation;
188  SourceLocation InnerTeamsRegionLoc;
189  /// Reference to the taskgroup task_reduction reference expression.
190  Expr *TaskgroupReductionRef = nullptr;
191  llvm::DenseSet<QualType> MappedClassesQualTypes;
192  SmallVector<Expr *, 4> InnerUsedAllocators;
193  llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
194  /// List of globals marked as declare target link in this target region
195  /// (isOpenMPTargetExecutionDirective(Directive) == true).
196  llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
197  /// List of decls used in inclusive/exclusive clauses of the scan directive.
198  llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
199  llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
200  UsesAllocatorsDecls;
201  /// Data is required on creating capture fields for implicit
202  /// default first|private clause.
203  struct ImplicitDefaultFDInfoTy {
204  /// Field decl.
205  const FieldDecl *FD = nullptr;
206  /// Nesting stack level
207  size_t StackLevel = 0;
208  /// Capture variable decl.
209  VarDecl *VD = nullptr;
210  ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
211  VarDecl *VD)
212  : FD(FD), StackLevel(StackLevel), VD(VD) {}
213  };
214  /// List of captured fields
216  ImplicitDefaultFirstprivateFDs;
217  Expr *DeclareMapperVar = nullptr;
218  SmallVector<VarDecl *, 16> IteratorVarDecls;
219  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
220  Scope *CurScope, SourceLocation Loc)
221  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
222  ConstructLoc(Loc) {}
223  SharingMapTy() = default;
224  };
225 
226  using StackTy = SmallVector<SharingMapTy, 4>;
227 
228  /// Stack of used declaration and their data-sharing attributes.
229  DeclSAMapTy Threadprivates;
230  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
232  /// true, if check for DSA must be from parent directive, false, if
233  /// from current directive.
234  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
235  Sema &SemaRef;
236  bool ForceCapturing = false;
237  /// true if all the variables in the target executable directives must be
238  /// captured by reference.
239  bool ForceCaptureByReferenceInTargetExecutable = false;
240  CriticalsWithHintsTy Criticals;
241  unsigned IgnoredStackElements = 0;
242 
243  /// Iterators over the stack iterate in order from innermost to outermost
244  /// directive.
245  using const_iterator = StackTy::const_reverse_iterator;
246  const_iterator begin() const {
247  return Stack.empty() ? const_iterator()
248  : Stack.back().first.rbegin() + IgnoredStackElements;
249  }
250  const_iterator end() const {
251  return Stack.empty() ? const_iterator() : Stack.back().first.rend();
252  }
253  using iterator = StackTy::reverse_iterator;
254  iterator begin() {
255  return Stack.empty() ? iterator()
256  : Stack.back().first.rbegin() + IgnoredStackElements;
257  }
258  iterator end() {
259  return Stack.empty() ? iterator() : Stack.back().first.rend();
260  }
261 
262  // Convenience operations to get at the elements of the stack.
263 
264  bool isStackEmpty() const {
265  return Stack.empty() ||
266  Stack.back().second != CurrentNonCapturingFunctionScope ||
267  Stack.back().first.size() <= IgnoredStackElements;
268  }
269  size_t getStackSize() const {
270  return isStackEmpty() ? 0
271  : Stack.back().first.size() - IgnoredStackElements;
272  }
273 
274  SharingMapTy *getTopOfStackOrNull() {
275  size_t Size = getStackSize();
276  if (Size == 0)
277  return nullptr;
278  return &Stack.back().first[Size - 1];
279  }
280  const SharingMapTy *getTopOfStackOrNull() const {
281  return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
282  }
283  SharingMapTy &getTopOfStack() {
284  assert(!isStackEmpty() && "no current directive");
285  return *getTopOfStackOrNull();
286  }
287  const SharingMapTy &getTopOfStack() const {
288  return const_cast<DSAStackTy &>(*this).getTopOfStack();
289  }
290 
291  SharingMapTy *getSecondOnStackOrNull() {
292  size_t Size = getStackSize();
293  if (Size <= 1)
294  return nullptr;
295  return &Stack.back().first[Size - 2];
296  }
297  const SharingMapTy *getSecondOnStackOrNull() const {
298  return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
299  }
300 
301  /// Get the stack element at a certain level (previously returned by
302  /// \c getNestingLevel).
303  ///
304  /// Note that nesting levels count from outermost to innermost, and this is
305  /// the reverse of our iteration order where new inner levels are pushed at
306  /// the front of the stack.
307  SharingMapTy &getStackElemAtLevel(unsigned Level) {
308  assert(Level < getStackSize() && "no such stack element");
309  return Stack.back().first[Level];
310  }
311  const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
312  return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
313  }
314 
315  DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
316 
317  /// Checks if the variable is a local for OpenMP region.
318  bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
319 
320  /// Vector of previously declared requires directives
322  /// omp_allocator_handle_t type.
323  QualType OMPAllocatorHandleT;
324  /// omp_depend_t type.
325  QualType OMPDependT;
326  /// omp_event_handle_t type.
327  QualType OMPEventHandleT;
328  /// omp_alloctrait_t type.
329  QualType OMPAlloctraitT;
330  /// Expression for the predefined allocators.
331  Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
332  nullptr};
333  /// Vector of previously encountered target directives
334  SmallVector<SourceLocation, 2> TargetLocations;
335  SourceLocation AtomicLocation;
336  /// Vector of declare variant construct traits.
338 
339 public:
340  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
341 
342  /// Sets omp_allocator_handle_t type.
343  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
344  /// Gets omp_allocator_handle_t type.
345  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
346  /// Sets omp_alloctrait_t type.
347  void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
348  /// Gets omp_alloctrait_t type.
349  QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
350  /// Sets the given default allocator.
351  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
352  Expr *Allocator) {
353  OMPPredefinedAllocators[AllocatorKind] = Allocator;
354  }
355  /// Returns the specified default allocator.
356  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
357  return OMPPredefinedAllocators[AllocatorKind];
358  }
359  /// Sets omp_depend_t type.
360  void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
361  /// Gets omp_depend_t type.
362  QualType getOMPDependT() const { return OMPDependT; }
363 
364  /// Sets omp_event_handle_t type.
365  void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
366  /// Gets omp_event_handle_t type.
367  QualType getOMPEventHandleT() const { return OMPEventHandleT; }
368 
369  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
370  OpenMPClauseKind getClauseParsingMode() const {
371  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
372  return ClauseKindMode;
373  }
374  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
375 
376  bool isBodyComplete() const {
377  const SharingMapTy *Top = getTopOfStackOrNull();
378  return Top && Top->BodyComplete;
379  }
380  void setBodyComplete() { getTopOfStack().BodyComplete = true; }
381 
382  bool isForceVarCapturing() const { return ForceCapturing; }
383  void setForceVarCapturing(bool V) { ForceCapturing = V; }
384 
385  void setForceCaptureByReferenceInTargetExecutable(bool V) {
386  ForceCaptureByReferenceInTargetExecutable = V;
387  }
388  bool isForceCaptureByReferenceInTargetExecutable() const {
389  return ForceCaptureByReferenceInTargetExecutable;
390  }
391 
392  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
393  Scope *CurScope, SourceLocation Loc) {
394  assert(!IgnoredStackElements &&
395  "cannot change stack while ignoring elements");
396  if (Stack.empty() ||
397  Stack.back().second != CurrentNonCapturingFunctionScope)
398  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
399  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
400  Stack.back().first.back().DefaultAttrLoc = Loc;
401  }
402 
403  void pop() {
404  assert(!IgnoredStackElements &&
405  "cannot change stack while ignoring elements");
406  assert(!Stack.back().first.empty() &&
407  "Data-sharing attributes stack is empty!");
408  Stack.back().first.pop_back();
409  }
410 
411  /// RAII object to temporarily leave the scope of a directive when we want to
412  /// logically operate in its parent.
413  class ParentDirectiveScope {
414  DSAStackTy &Self;
415  bool Active;
416 
417  public:
418  ParentDirectiveScope(DSAStackTy &Self, bool Activate)
419  : Self(Self), Active(false) {
420  if (Activate)
421  enable();
422  }
423  ~ParentDirectiveScope() { disable(); }
424  void disable() {
425  if (Active) {
426  --Self.IgnoredStackElements;
427  Active = false;
428  }
429  }
430  void enable() {
431  if (!Active) {
432  ++Self.IgnoredStackElements;
433  Active = true;
434  }
435  }
436  };
437 
438  /// Marks that we're started loop parsing.
439  void loopInit() {
440  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
441  "Expected loop-based directive.");
442  getTopOfStack().LoopStart = true;
443  }
444  /// Start capturing of the variables in the loop context.
445  void loopStart() {
446  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
447  "Expected loop-based directive.");
448  getTopOfStack().LoopStart = false;
449  }
450  /// true, if variables are captured, false otherwise.
451  bool isLoopStarted() const {
452  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
453  "Expected loop-based directive.");
454  return !getTopOfStack().LoopStart;
455  }
456  /// Marks (or clears) declaration as possibly loop counter.
457  void resetPossibleLoopCounter(const Decl *D = nullptr) {
458  getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
459  }
460  /// Gets the possible loop counter decl.
461  const Decl *getPossiblyLoopCunter() const {
462  return getTopOfStack().PossiblyLoopCounter;
463  }
464  /// Start new OpenMP region stack in new non-capturing function.
465  void pushFunction() {
466  assert(!IgnoredStackElements &&
467  "cannot change stack while ignoring elements");
468  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
469  assert(!isa<CapturingScopeInfo>(CurFnScope));
470  CurrentNonCapturingFunctionScope = CurFnScope;
471  }
472  /// Pop region stack for non-capturing function.
473  void popFunction(const FunctionScopeInfo *OldFSI) {
474  assert(!IgnoredStackElements &&
475  "cannot change stack while ignoring elements");
476  if (!Stack.empty() && Stack.back().second == OldFSI) {
477  assert(Stack.back().first.empty());
478  Stack.pop_back();
479  }
480  CurrentNonCapturingFunctionScope = nullptr;
481  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
482  if (!isa<CapturingScopeInfo>(FSI)) {
483  CurrentNonCapturingFunctionScope = FSI;
484  break;
485  }
486  }
487  }
488 
489  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
490  Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
491  }
492  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
493  getCriticalWithHint(const DeclarationNameInfo &Name) const {
494  auto I = Criticals.find(Name.getAsString());
495  if (I != Criticals.end())
496  return I->second;
497  return std::make_pair(nullptr, llvm::APSInt());
498  }
499  /// If 'aligned' declaration for given variable \a D was not seen yet,
500  /// add it and return NULL; otherwise return previous occurrence's expression
501  /// for diagnostics.
502  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
503  /// If 'nontemporal' declaration for given variable \a D was not seen yet,
504  /// add it and return NULL; otherwise return previous occurrence's expression
505  /// for diagnostics.
506  const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
507 
508  /// Register specified variable as loop control variable.
509  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
510  /// Check if the specified variable is a loop control variable for
511  /// current region.
512  /// \return The index of the loop control variable in the list of associated
513  /// for-loops (from outer to inner).
514  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
515  /// Check if the specified variable is a loop control variable for
516  /// parent region.
517  /// \return The index of the loop control variable in the list of associated
518  /// for-loops (from outer to inner).
519  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
520  /// Check if the specified variable is a loop control variable for
521  /// current region.
522  /// \return The index of the loop control variable in the list of associated
523  /// for-loops (from outer to inner).
524  const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
525  unsigned Level) const;
526  /// Get the loop control variable for the I-th loop (or nullptr) in
527  /// parent directive.
528  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
529 
530  /// Marks the specified decl \p D as used in scan directive.
531  void markDeclAsUsedInScanDirective(ValueDecl *D) {
532  if (SharingMapTy *Stack = getSecondOnStackOrNull())
533  Stack->UsedInScanDirective.insert(D);
534  }
535 
536  /// Checks if the specified declaration was used in the inner scan directive.
537  bool isUsedInScanDirective(ValueDecl *D) const {
538  if (const SharingMapTy *Stack = getTopOfStackOrNull())
539  return Stack->UsedInScanDirective.contains(D);
540  return false;
541  }
542 
543  /// Adds explicit data sharing attribute to the specified declaration.
544  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
545  DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
546  bool AppliedToPointee = false);
547 
548  /// Adds additional information for the reduction items with the reduction id
549  /// represented as an operator.
550  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
551  BinaryOperatorKind BOK);
552  /// Adds additional information for the reduction items with the reduction id
553  /// represented as reduction identifier.
554  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
555  const Expr *ReductionRef);
556  /// Returns the location and reduction operation from the innermost parent
557  /// region for the given \p D.
558  const DSAVarData
559  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
560  BinaryOperatorKind &BOK,
561  Expr *&TaskgroupDescriptor) const;
562  /// Returns the location and reduction operation from the innermost parent
563  /// region for the given \p D.
564  const DSAVarData
565  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
566  const Expr *&ReductionRef,
567  Expr *&TaskgroupDescriptor) const;
568  /// Return reduction reference expression for the current taskgroup or
569  /// parallel/worksharing directives with task reductions.
570  Expr *getTaskgroupReductionRef() const {
571  assert((getTopOfStack().Directive == OMPD_taskgroup ||
572  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
573  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
574  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
575  "taskgroup reference expression requested for non taskgroup or "
576  "parallel/worksharing directive.");
577  return getTopOfStack().TaskgroupReductionRef;
578  }
579  /// Checks if the given \p VD declaration is actually a taskgroup reduction
580  /// descriptor variable at the \p Level of OpenMP regions.
581  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
582  return getStackElemAtLevel(Level).TaskgroupReductionRef &&
583  cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
584  ->getDecl() == VD;
585  }
586 
587  /// Returns data sharing attributes from top of the stack for the
588  /// specified declaration.
589  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
590  /// Returns data-sharing attributes for the specified declaration.
591  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
592  /// Returns data-sharing attributes for the specified declaration.
593  const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
594  /// Checks if the specified variables has data-sharing attributes which
595  /// match specified \a CPred predicate in any directive which matches \a DPred
596  /// predicate.
597  const DSAVarData
598  hasDSA(ValueDecl *D,
599  const llvm::function_ref<bool(OpenMPClauseKind, bool,
600  DefaultDataSharingAttributes)>
601  CPred,
602  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
603  bool FromParent) const;
604  /// Checks if the specified variables has data-sharing attributes which
605  /// match specified \a CPred predicate in any innermost directive which
606  /// matches \a DPred predicate.
607  const DSAVarData
608  hasInnermostDSA(ValueDecl *D,
609  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
610  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
611  bool FromParent) const;
612  /// Checks if the specified variables has explicit data-sharing
613  /// attributes which match specified \a CPred predicate at the specified
614  /// OpenMP region.
615  bool
616  hasExplicitDSA(const ValueDecl *D,
617  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
618  unsigned Level, bool NotLastprivate = false) const;
619 
620  /// Returns true if the directive at level \Level matches in the
621  /// specified \a DPred predicate.
622  bool hasExplicitDirective(
623  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
624  unsigned Level) const;
625 
626  /// Finds a directive which matches specified \a DPred predicate.
627  bool hasDirective(
628  const llvm::function_ref<bool(
630  DPred,
631  bool FromParent) const;
632 
633  /// Returns currently analyzed directive.
634  OpenMPDirectiveKind getCurrentDirective() const {
635  const SharingMapTy *Top = getTopOfStackOrNull();
636  return Top ? Top->Directive : OMPD_unknown;
637  }
638  /// Returns directive kind at specified level.
639  OpenMPDirectiveKind getDirective(unsigned Level) const {
640  assert(!isStackEmpty() && "No directive at specified level.");
641  return getStackElemAtLevel(Level).Directive;
642  }
643  /// Returns the capture region at the specified level.
644  OpenMPDirectiveKind getCaptureRegion(unsigned Level,
645  unsigned OpenMPCaptureLevel) const {
647  getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
648  return CaptureRegions[OpenMPCaptureLevel];
649  }
650  /// Returns parent directive.
651  OpenMPDirectiveKind getParentDirective() const {
652  const SharingMapTy *Parent = getSecondOnStackOrNull();
653  return Parent ? Parent->Directive : OMPD_unknown;
654  }
655 
656  /// Add requires decl to internal vector
657  void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
658 
659  /// Checks if the defined 'requires' directive has specified type of clause.
660  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
661  return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
662  return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
663  return isa<ClauseType>(C);
664  });
665  });
666  }
667 
668  /// Checks for a duplicate clause amongst previously declared requires
669  /// directives
670  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
671  bool IsDuplicate = false;
672  for (OMPClause *CNew : ClauseList) {
673  for (const OMPRequiresDecl *D : RequiresDecls) {
674  for (const OMPClause *CPrev : D->clauselists()) {
675  if (CNew->getClauseKind() == CPrev->getClauseKind()) {
676  SemaRef.Diag(CNew->getBeginLoc(),
677  diag::err_omp_requires_clause_redeclaration)
678  << getOpenMPClauseName(CNew->getClauseKind());
679  SemaRef.Diag(CPrev->getBeginLoc(),
680  diag::note_omp_requires_previous_clause)
681  << getOpenMPClauseName(CPrev->getClauseKind());
682  IsDuplicate = true;
683  }
684  }
685  }
686  }
687  return IsDuplicate;
688  }
689 
690  /// Add location of previously encountered target to internal vector
691  void addTargetDirLocation(SourceLocation LocStart) {
692  TargetLocations.push_back(LocStart);
693  }
694 
695  /// Add location for the first encountered atomicc directive.
696  void addAtomicDirectiveLoc(SourceLocation Loc) {
697  if (AtomicLocation.isInvalid())
698  AtomicLocation = Loc;
699  }
700 
701  /// Returns the location of the first encountered atomic directive in the
702  /// module.
703  SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
704 
705  // Return previously encountered target region locations.
706  ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
707  return TargetLocations;
708  }
709 
710  /// Set default data sharing attribute to none.
711  void setDefaultDSANone(SourceLocation Loc) {
712  getTopOfStack().DefaultAttr = DSA_none;
713  getTopOfStack().DefaultAttrLoc = Loc;
714  }
715  /// Set default data sharing attribute to shared.
716  void setDefaultDSAShared(SourceLocation Loc) {
717  getTopOfStack().DefaultAttr = DSA_shared;
718  getTopOfStack().DefaultAttrLoc = Loc;
719  }
720  /// Set default data sharing attribute to private.
721  void setDefaultDSAPrivate(SourceLocation Loc) {
722  getTopOfStack().DefaultAttr = DSA_private;
723  getTopOfStack().DefaultAttrLoc = Loc;
724  }
725  /// Set default data sharing attribute to firstprivate.
726  void setDefaultDSAFirstPrivate(SourceLocation Loc) {
727  getTopOfStack().DefaultAttr = DSA_firstprivate;
728  getTopOfStack().DefaultAttrLoc = Loc;
729  }
730  /// Set default data mapping attribute to Modifier:Kind
731  void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
733  DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
734  DMI.ImplicitBehavior = M;
735  DMI.SLoc = Loc;
736  }
737  /// Check whether the implicit-behavior has been set in defaultmap
738  bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
739  if (VariableCategory == OMPC_DEFAULTMAP_unknown)
740  return getTopOfStack()
741  .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
742  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
743  getTopOfStack()
744  .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
745  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
746  getTopOfStack()
747  .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
748  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
749  return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
751  }
752 
753  ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
754  return ConstructTraits;
755  }
756  void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
757  bool ScopeEntry) {
758  if (ScopeEntry)
759  ConstructTraits.append(Traits.begin(), Traits.end());
760  else
761  for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
762  llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
763  assert(Top == Trait && "Something left a trait on the stack!");
764  (void)Trait;
765  (void)Top;
766  }
767  }
768 
769  DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
770  return getStackSize() <= Level ? DSA_unspecified
771  : getStackElemAtLevel(Level).DefaultAttr;
772  }
773  DefaultDataSharingAttributes getDefaultDSA() const {
774  return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
775  }
776  SourceLocation getDefaultDSALocation() const {
777  return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
778  }
780  getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
781  return isStackEmpty()
783  : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
784  }
786  getDefaultmapModifierAtLevel(unsigned Level,
788  return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
789  }
790  bool isDefaultmapCapturedByRef(unsigned Level,
793  getDefaultmapModifierAtLevel(Level, Kind);
794  if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
795  return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
796  (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
797  (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
798  (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
799  }
800  return true;
801  }
802  static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
804  switch (Kind) {
805  case OMPC_DEFAULTMAP_scalar:
806  case OMPC_DEFAULTMAP_pointer:
807  return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
808  (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
809  (M == OMPC_DEFAULTMAP_MODIFIER_default);
810  case OMPC_DEFAULTMAP_aggregate:
811  return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
812  default:
813  break;
814  }
815  llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
816  }
817  bool mustBeFirstprivateAtLevel(unsigned Level,
820  getDefaultmapModifierAtLevel(Level, Kind);
821  return mustBeFirstprivateBase(M, Kind);
822  }
823  bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
824  OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
825  return mustBeFirstprivateBase(M, Kind);
826  }
827 
828  /// Checks if the specified variable is a threadprivate.
829  bool isThreadPrivate(VarDecl *D) {
830  const DSAVarData DVar = getTopDSA(D, false);
831  return isOpenMPThreadPrivate(DVar.CKind);
832  }
833 
834  /// Marks current region as ordered (it has an 'ordered' clause).
835  void setOrderedRegion(bool IsOrdered, const Expr *Param,
836  OMPOrderedClause *Clause) {
837  if (IsOrdered)
838  getTopOfStack().OrderedRegion.emplace(Param, Clause);
839  else
840  getTopOfStack().OrderedRegion.reset();
841  }
842  /// Returns true, if region is ordered (has associated 'ordered' clause),
843  /// false - otherwise.
844  bool isOrderedRegion() const {
845  if (const SharingMapTy *Top = getTopOfStackOrNull())
846  return Top->OrderedRegion.has_value();
847  return false;
848  }
849  /// Returns optional parameter for the ordered region.
850  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
851  if (const SharingMapTy *Top = getTopOfStackOrNull())
852  if (Top->OrderedRegion)
853  return *Top->OrderedRegion;
854  return std::make_pair(nullptr, nullptr);
855  }
856  /// Returns true, if parent region is ordered (has associated
857  /// 'ordered' clause), false - otherwise.
858  bool isParentOrderedRegion() const {
859  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
860  return Parent->OrderedRegion.has_value();
861  return false;
862  }
863  /// Returns optional parameter for the ordered region.
864  std::pair<const Expr *, OMPOrderedClause *>
865  getParentOrderedRegionParam() const {
866  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
867  if (Parent->OrderedRegion)
868  return *Parent->OrderedRegion;
869  return std::make_pair(nullptr, nullptr);
870  }
871  /// Marks current region as having an 'order' clause.
872  void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
873  getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
874  }
875  /// Returns true, if parent region is order (has associated
876  /// 'order' clause), false - otherwise.
877  bool isParentOrderConcurrent() const {
878  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
879  return Parent->RegionHasOrderConcurrent;
880  return false;
881  }
882  /// Marks current region as nowait (it has a 'nowait' clause).
883  void setNowaitRegion(bool IsNowait = true) {
884  getTopOfStack().NowaitRegion = IsNowait;
885  }
886  /// Returns true, if parent region is nowait (has associated
887  /// 'nowait' clause), false - otherwise.
888  bool isParentNowaitRegion() const {
889  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890  return Parent->NowaitRegion;
891  return false;
892  }
893  /// Marks current region as untied (it has a 'untied' clause).
894  void setUntiedRegion(bool IsUntied = true) {
895  getTopOfStack().UntiedRegion = IsUntied;
896  }
897  /// Return true if current region is untied.
898  bool isUntiedRegion() const {
899  const SharingMapTy *Top = getTopOfStackOrNull();
900  return Top ? Top->UntiedRegion : false;
901  }
902  /// Marks parent region as cancel region.
903  void setParentCancelRegion(bool Cancel = true) {
904  if (SharingMapTy *Parent = getSecondOnStackOrNull())
905  Parent->CancelRegion |= Cancel;
906  }
907  /// Return true if current region has inner cancel construct.
908  bool isCancelRegion() const {
909  const SharingMapTy *Top = getTopOfStackOrNull();
910  return Top ? Top->CancelRegion : false;
911  }
912 
913  /// Mark that parent region already has scan directive.
914  void setParentHasScanDirective(SourceLocation Loc) {
915  if (SharingMapTy *Parent = getSecondOnStackOrNull())
916  Parent->PrevScanLocation = Loc;
917  }
918  /// Return true if current region has inner cancel construct.
919  bool doesParentHasScanDirective() const {
920  const SharingMapTy *Top = getSecondOnStackOrNull();
921  return Top ? Top->PrevScanLocation.isValid() : false;
922  }
923  /// Return true if current region has inner cancel construct.
924  SourceLocation getParentScanDirectiveLoc() const {
925  const SharingMapTy *Top = getSecondOnStackOrNull();
926  return Top ? Top->PrevScanLocation : SourceLocation();
927  }
928  /// Mark that parent region already has ordered directive.
929  void setParentHasOrderedDirective(SourceLocation Loc) {
930  if (SharingMapTy *Parent = getSecondOnStackOrNull())
931  Parent->PrevOrderedLocation = Loc;
932  }
933  /// Return true if current region has inner ordered construct.
934  bool doesParentHasOrderedDirective() const {
935  const SharingMapTy *Top = getSecondOnStackOrNull();
936  return Top ? Top->PrevOrderedLocation.isValid() : false;
937  }
938  /// Returns the location of the previously specified ordered directive.
939  SourceLocation getParentOrderedDirectiveLoc() const {
940  const SharingMapTy *Top = getSecondOnStackOrNull();
941  return Top ? Top->PrevOrderedLocation : SourceLocation();
942  }
943 
944  /// Set collapse value for the region.
945  void setAssociatedLoops(unsigned Val) {
946  getTopOfStack().AssociatedLoops = Val;
947  if (Val > 1)
948  getTopOfStack().HasMutipleLoops = true;
949  }
950  /// Return collapse value for region.
951  unsigned getAssociatedLoops() const {
952  const SharingMapTy *Top = getTopOfStackOrNull();
953  return Top ? Top->AssociatedLoops : 0;
954  }
955  /// Returns true if the construct is associated with multiple loops.
956  bool hasMutipleLoops() const {
957  const SharingMapTy *Top = getTopOfStackOrNull();
958  return Top ? Top->HasMutipleLoops : false;
959  }
960 
961  /// Marks current target region as one with closely nested teams
962  /// region.
963  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
964  if (SharingMapTy *Parent = getSecondOnStackOrNull())
965  Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
966  }
967  /// Returns true, if current region has closely nested teams region.
968  bool hasInnerTeamsRegion() const {
969  return getInnerTeamsRegionLoc().isValid();
970  }
971  /// Returns location of the nested teams region (if any).
972  SourceLocation getInnerTeamsRegionLoc() const {
973  const SharingMapTy *Top = getTopOfStackOrNull();
974  return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
975  }
976 
977  Scope *getCurScope() const {
978  const SharingMapTy *Top = getTopOfStackOrNull();
979  return Top ? Top->CurScope : nullptr;
980  }
981  void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
982  SourceLocation getConstructLoc() const {
983  const SharingMapTy *Top = getTopOfStackOrNull();
984  return Top ? Top->ConstructLoc : SourceLocation();
985  }
986 
987  /// Do the check specified in \a Check to all component lists and return true
988  /// if any issue is found.
989  bool checkMappableExprComponentListsForDecl(
990  const ValueDecl *VD, bool CurrentRegionOnly,
991  const llvm::function_ref<
994  Check) const {
995  if (isStackEmpty())
996  return false;
997  auto SI = begin();
998  auto SE = end();
999 
1000  if (SI == SE)
1001  return false;
1002 
1003  if (CurrentRegionOnly)
1004  SE = std::next(SI);
1005  else
1006  std::advance(SI, 1);
1007 
1008  for (; SI != SE; ++SI) {
1009  auto MI = SI->MappedExprComponents.find(VD);
1010  if (MI != SI->MappedExprComponents.end())
1012  MI->second.Components)
1013  if (Check(L, MI->second.Kind))
1014  return true;
1015  }
1016  return false;
1017  }
1018 
1019  /// Do the check specified in \a Check to all component lists at a given level
1020  /// and return true if any issue is found.
1021  bool checkMappableExprComponentListsForDeclAtLevel(
1022  const ValueDecl *VD, unsigned Level,
1023  const llvm::function_ref<
1026  Check) const {
1027  if (getStackSize() <= Level)
1028  return false;
1029 
1030  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1031  auto MI = StackElem.MappedExprComponents.find(VD);
1032  if (MI != StackElem.MappedExprComponents.end())
1034  MI->second.Components)
1035  if (Check(L, MI->second.Kind))
1036  return true;
1037  return false;
1038  }
1039 
1040  /// Create a new mappable expression component list associated with a given
1041  /// declaration and initialize it with the provided list of components.
1042  void addMappableExpressionComponents(
1043  const ValueDecl *VD,
1045  OpenMPClauseKind WhereFoundClauseKind) {
1046  MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1047  // Create new entry and append the new components there.
1048  MEC.Components.resize(MEC.Components.size() + 1);
1049  MEC.Components.back().append(Components.begin(), Components.end());
1050  MEC.Kind = WhereFoundClauseKind;
1051  }
1052 
1053  unsigned getNestingLevel() const {
1054  assert(!isStackEmpty());
1055  return getStackSize() - 1;
1056  }
1057  void addDoacrossDependClause(OMPDependClause *C,
1058  const OperatorOffsetTy &OpsOffs) {
1059  SharingMapTy *Parent = getSecondOnStackOrNull();
1060  assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1061  Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1062  }
1063  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1064  getDoacrossDependClauses() const {
1065  const SharingMapTy &StackElem = getTopOfStack();
1066  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1067  const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1068  return llvm::make_range(Ref.begin(), Ref.end());
1069  }
1070  return llvm::make_range(StackElem.DoacrossDepends.end(),
1071  StackElem.DoacrossDepends.end());
1072  }
1073 
1074  // Store types of classes which have been explicitly mapped
1075  void addMappedClassesQualTypes(QualType QT) {
1076  SharingMapTy &StackElem = getTopOfStack();
1077  StackElem.MappedClassesQualTypes.insert(QT);
1078  }
1079 
1080  // Return set of mapped classes types
1081  bool isClassPreviouslyMapped(QualType QT) const {
1082  const SharingMapTy &StackElem = getTopOfStack();
1083  return StackElem.MappedClassesQualTypes.contains(QT);
1084  }
1085 
1086  /// Adds global declare target to the parent target region.
1087  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1088  assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1089  E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1090  "Expected declare target link global.");
1091  for (auto &Elem : *this) {
1092  if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1093  Elem.DeclareTargetLinkVarDecls.push_back(E);
1094  return;
1095  }
1096  }
1097  }
1098 
1099  /// Returns the list of globals with declare target link if current directive
1100  /// is target.
1101  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1102  assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1103  "Expected target executable directive.");
1104  return getTopOfStack().DeclareTargetLinkVarDecls;
1105  }
1106 
1107  /// Adds list of allocators expressions.
1108  void addInnerAllocatorExpr(Expr *E) {
1109  getTopOfStack().InnerUsedAllocators.push_back(E);
1110  }
1111  /// Return list of used allocators.
1112  ArrayRef<Expr *> getInnerAllocators() const {
1113  return getTopOfStack().InnerUsedAllocators;
1114  }
1115  /// Marks the declaration as implicitly firstprivate nin the task-based
1116  /// regions.
1117  void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1118  getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1119  }
1120  /// Checks if the decl is implicitly firstprivate in the task-based region.
1121  bool isImplicitTaskFirstprivate(Decl *D) const {
1122  return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1123  }
1124 
1125  /// Marks decl as used in uses_allocators clause as the allocator.
1126  void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1127  getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1128  }
1129  /// Checks if specified decl is used in uses allocator clause as the
1130  /// allocator.
1131  std::optional<UsesAllocatorsDeclKind>
1132  isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1133  const SharingMapTy &StackElem = getTopOfStack();
1134  auto I = StackElem.UsesAllocatorsDecls.find(D);
1135  if (I == StackElem.UsesAllocatorsDecls.end())
1136  return std::nullopt;
1137  return I->getSecond();
1138  }
1139  std::optional<UsesAllocatorsDeclKind>
1140  isUsesAllocatorsDecl(const Decl *D) const {
1141  const SharingMapTy &StackElem = getTopOfStack();
1142  auto I = StackElem.UsesAllocatorsDecls.find(D);
1143  if (I == StackElem.UsesAllocatorsDecls.end())
1144  return std::nullopt;
1145  return I->getSecond();
1146  }
1147 
1148  void addDeclareMapperVarRef(Expr *Ref) {
1149  SharingMapTy &StackElem = getTopOfStack();
1150  StackElem.DeclareMapperVar = Ref;
1151  }
1152  const Expr *getDeclareMapperVarRef() const {
1153  const SharingMapTy *Top = getTopOfStackOrNull();
1154  return Top ? Top->DeclareMapperVar : nullptr;
1155  }
1156 
1157  /// Add a new iterator variable.
1158  void addIteratorVarDecl(VarDecl *VD) {
1159  SharingMapTy &StackElem = getTopOfStack();
1160  StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1161  }
1162  /// Check if variable declaration is an iterator VarDecl.
1163  bool isIteratorVarDecl(const VarDecl *VD) const {
1164  const SharingMapTy *Top = getTopOfStackOrNull();
1165  if (!Top)
1166  return false;
1167 
1168  return llvm::any_of(Top->IteratorVarDecls, [VD](const VarDecl *IteratorVD) {
1169  return IteratorVD == VD->getCanonicalDecl();
1170  });
1171  }
1172  /// get captured field from ImplicitDefaultFirstprivateFDs
1173  VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1174  const_iterator I = begin();
1175  const_iterator EndI = end();
1176  size_t StackLevel = getStackSize();
1177  for (; I != EndI; ++I) {
1178  if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1179  break;
1180  StackLevel--;
1181  }
1182  assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1183  if (I == EndI)
1184  return nullptr;
1185  for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1186  if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1187  return IFD.VD;
1188  return nullptr;
1189  }
1190  /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1191  bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1192  const_iterator I = begin();
1193  const_iterator EndI = end();
1194  for (; I != EndI; ++I)
1195  if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1196  break;
1197  if (I == EndI)
1198  return false;
1199  for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1200  if (IFD.VD == VD)
1201  return true;
1202  return false;
1203  }
1204  /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1205  void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1206  iterator I = begin();
1207  const_iterator EndI = end();
1208  size_t StackLevel = getStackSize();
1209  for (; I != EndI; ++I) {
1210  if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1211  I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1212  break;
1213  }
1214  StackLevel--;
1215  }
1216  assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1217  }
1218 };
1219 
1220 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1221  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1222 }
1223 
1224 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1225  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1226  DKind == OMPD_unknown;
1227 }
1228 
1229 } // namespace
1230 
1231 static const Expr *getExprAsWritten(const Expr *E) {
1232  if (const auto *FE = dyn_cast<FullExpr>(E))
1233  E = FE->getSubExpr();
1234 
1235  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1236  E = MTE->getSubExpr();
1237 
1238  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1239  E = Binder->getSubExpr();
1240 
1241  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1242  E = ICE->getSubExprAsWritten();
1243  return E->IgnoreParens();
1244 }
1245 
1247  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1248 }
1249 
1250 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1251  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1252  if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1253  D = ME->getMemberDecl();
1254  const auto *VD = dyn_cast<VarDecl>(D);
1255  const auto *FD = dyn_cast<FieldDecl>(D);
1256  if (VD != nullptr) {
1257  VD = VD->getCanonicalDecl();
1258  D = VD;
1259  } else {
1260  assert(FD);
1261  FD = FD->getCanonicalDecl();
1262  D = FD;
1263  }
1264  return D;
1265 }
1266 
1268  return const_cast<ValueDecl *>(
1269  getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1270 }
1271 
1272 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1273  ValueDecl *D) const {
1274  D = getCanonicalDecl(D);
1275  auto *VD = dyn_cast<VarDecl>(D);
1276  const auto *FD = dyn_cast<FieldDecl>(D);
1277  DSAVarData DVar;
1278  if (Iter == end()) {
1279  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1280  // in a region but not in construct]
1281  // File-scope or namespace-scope variables referenced in called routines
1282  // in the region are shared unless they appear in a threadprivate
1283  // directive.
1284  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1285  DVar.CKind = OMPC_shared;
1286 
1287  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1288  // in a region but not in construct]
1289  // Variables with static storage duration that are declared in called
1290  // routines in the region are shared.
1291  if (VD && VD->hasGlobalStorage())
1292  DVar.CKind = OMPC_shared;
1293 
1294  // Non-static data members are shared by default.
1295  if (FD)
1296  DVar.CKind = OMPC_shared;
1297 
1298  return DVar;
1299  }
1300 
1301  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1302  // in a Construct, C/C++, predetermined, p.1]
1303  // Variables with automatic storage duration that are declared in a scope
1304  // inside the construct are private.
1305  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1306  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1307  DVar.CKind = OMPC_private;
1308  return DVar;
1309  }
1310 
1311  DVar.DKind = Iter->Directive;
1312  // Explicitly specified attributes and local variables with predetermined
1313  // attributes.
1314  if (Iter->SharingMap.count(D)) {
1315  const DSAInfo &Data = Iter->SharingMap.lookup(D);
1316  DVar.RefExpr = Data.RefExpr.getPointer();
1317  DVar.PrivateCopy = Data.PrivateCopy;
1318  DVar.CKind = Data.Attributes;
1319  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1320  DVar.Modifier = Data.Modifier;
1321  DVar.AppliedToPointee = Data.AppliedToPointee;
1322  return DVar;
1323  }
1324 
1325  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1326  // in a Construct, C/C++, implicitly determined, p.1]
1327  // In a parallel or task construct, the data-sharing attributes of these
1328  // variables are determined by the default clause, if present.
1329  switch (Iter->DefaultAttr) {
1330  case DSA_shared:
1331  DVar.CKind = OMPC_shared;
1332  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1333  return DVar;
1334  case DSA_none:
1335  return DVar;
1336  case DSA_firstprivate:
1337  if (VD && VD->getStorageDuration() == SD_Static &&
1338  VD->getDeclContext()->isFileContext()) {
1339  DVar.CKind = OMPC_unknown;
1340  } else {
1341  DVar.CKind = OMPC_firstprivate;
1342  }
1343  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1344  return DVar;
1345  case DSA_private:
1346  // each variable with static storage duration that is declared
1347  // in a namespace or global scope and referenced in the construct,
1348  // and that does not have a predetermined data-sharing attribute
1349  if (VD && VD->getStorageDuration() == SD_Static &&
1350  VD->getDeclContext()->isFileContext()) {
1351  DVar.CKind = OMPC_unknown;
1352  } else {
1353  DVar.CKind = OMPC_private;
1354  }
1355  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1356  return DVar;
1357  case DSA_unspecified:
1358  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1359  // in a Construct, implicitly determined, p.2]
1360  // In a parallel construct, if no default clause is present, these
1361  // variables are shared.
1362  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1363  if ((isOpenMPParallelDirective(DVar.DKind) &&
1364  !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1365  isOpenMPTeamsDirective(DVar.DKind)) {
1366  DVar.CKind = OMPC_shared;
1367  return DVar;
1368  }
1369 
1370  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1371  // in a Construct, implicitly determined, p.4]
1372  // In a task construct, if no default clause is present, a variable that in
1373  // the enclosing context is determined to be shared by all implicit tasks
1374  // bound to the current team is shared.
1375  if (isOpenMPTaskingDirective(DVar.DKind)) {
1376  DSAVarData DVarTemp;
1377  const_iterator I = Iter, E = end();
1378  do {
1379  ++I;
1380  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1381  // Referenced in a Construct, implicitly determined, p.6]
1382  // In a task construct, if no default clause is present, a variable
1383  // whose data-sharing attribute is not determined by the rules above is
1384  // firstprivate.
1385  DVarTemp = getDSA(I, D);
1386  if (DVarTemp.CKind != OMPC_shared) {
1387  DVar.RefExpr = nullptr;
1388  DVar.CKind = OMPC_firstprivate;
1389  return DVar;
1390  }
1391  } while (I != E && !isImplicitTaskingRegion(I->Directive));
1392  DVar.CKind =
1393  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1394  return DVar;
1395  }
1396  }
1397  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1398  // in a Construct, implicitly determined, p.3]
1399  // For constructs other than task, if no default clause is present, these
1400  // variables inherit their data-sharing attributes from the enclosing
1401  // context.
1402  return getDSA(++Iter, D);
1403 }
1404 
1405 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1406  const Expr *NewDE) {
1407  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1408  D = getCanonicalDecl(D);
1409  SharingMapTy &StackElem = getTopOfStack();
1410  auto It = StackElem.AlignedMap.find(D);
1411  if (It == StackElem.AlignedMap.end()) {
1412  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1413  StackElem.AlignedMap[D] = NewDE;
1414  return nullptr;
1415  }
1416  assert(It->second && "Unexpected nullptr expr in the aligned map");
1417  return It->second;
1418 }
1419 
1420 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1421  const Expr *NewDE) {
1422  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1423  D = getCanonicalDecl(D);
1424  SharingMapTy &StackElem = getTopOfStack();
1425  auto It = StackElem.NontemporalMap.find(D);
1426  if (It == StackElem.NontemporalMap.end()) {
1427  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1428  StackElem.NontemporalMap[D] = NewDE;
1429  return nullptr;
1430  }
1431  assert(It->second && "Unexpected nullptr expr in the aligned map");
1432  return It->second;
1433 }
1434 
1435 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1436  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1437  D = getCanonicalDecl(D);
1438  SharingMapTy &StackElem = getTopOfStack();
1439  StackElem.LCVMap.try_emplace(
1440  D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1441 }
1442 
1443 const DSAStackTy::LCDeclInfo
1444 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1445  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1446  D = getCanonicalDecl(D);
1447  const SharingMapTy &StackElem = getTopOfStack();
1448  auto It = StackElem.LCVMap.find(D);
1449  if (It != StackElem.LCVMap.end())
1450  return It->second;
1451  return {0, nullptr};
1452 }
1453 
1454 const DSAStackTy::LCDeclInfo
1455 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1456  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1457  D = getCanonicalDecl(D);
1458  for (unsigned I = Level + 1; I > 0; --I) {
1459  const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1460  auto It = StackElem.LCVMap.find(D);
1461  if (It != StackElem.LCVMap.end())
1462  return It->second;
1463  }
1464  return {0, nullptr};
1465 }
1466 
1467 const DSAStackTy::LCDeclInfo
1468 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1469  const SharingMapTy *Parent = getSecondOnStackOrNull();
1470  assert(Parent && "Data-sharing attributes stack is empty");
1471  D = getCanonicalDecl(D);
1472  auto It = Parent->LCVMap.find(D);
1473  if (It != Parent->LCVMap.end())
1474  return It->second;
1475  return {0, nullptr};
1476 }
1477 
1478 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1479  const SharingMapTy *Parent = getSecondOnStackOrNull();
1480  assert(Parent && "Data-sharing attributes stack is empty");
1481  if (Parent->LCVMap.size() < I)
1482  return nullptr;
1483  for (const auto &Pair : Parent->LCVMap)
1484  if (Pair.second.first == I)
1485  return Pair.first;
1486  return nullptr;
1487 }
1488 
1489 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1490  DeclRefExpr *PrivateCopy, unsigned Modifier,
1491  bool AppliedToPointee) {
1492  D = getCanonicalDecl(D);
1493  if (A == OMPC_threadprivate) {
1494  DSAInfo &Data = Threadprivates[D];
1495  Data.Attributes = A;
1496  Data.RefExpr.setPointer(E);
1497  Data.PrivateCopy = nullptr;
1498  Data.Modifier = Modifier;
1499  } else {
1500  DSAInfo &Data = getTopOfStack().SharingMap[D];
1501  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1502  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1503  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1504  (isLoopControlVariable(D).first && A == OMPC_private));
1505  Data.Modifier = Modifier;
1506  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1507  Data.RefExpr.setInt(/*IntVal=*/true);
1508  return;
1509  }
1510  const bool IsLastprivate =
1511  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1512  Data.Attributes = A;
1513  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1514  Data.PrivateCopy = PrivateCopy;
1515  Data.AppliedToPointee = AppliedToPointee;
1516  if (PrivateCopy) {
1517  DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1518  Data.Modifier = Modifier;
1519  Data.Attributes = A;
1520  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1521  Data.PrivateCopy = nullptr;
1522  Data.AppliedToPointee = AppliedToPointee;
1523  }
1524  }
1525 }
1526 
1527 /// Build a variable declaration for OpenMP loop iteration variable.
1529  StringRef Name, const AttrVec *Attrs = nullptr,
1530  DeclRefExpr *OrigRef = nullptr) {
1531  DeclContext *DC = SemaRef.CurContext;
1532  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1533  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1534  auto *Decl =
1535  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1536  if (Attrs) {
1537  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1538  I != E; ++I)
1539  Decl->addAttr(*I);
1540  }
1541  Decl->setImplicit();
1542  if (OrigRef) {
1543  Decl->addAttr(
1544  OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1545  }
1546  return Decl;
1547 }
1548 
1550  SourceLocation Loc,
1551  bool RefersToCapture = false) {
1552  D->setReferenced();
1553  D->markUsed(S.Context);
1555  SourceLocation(), D, RefersToCapture, Loc, Ty,
1556  VK_LValue);
1557 }
1558 
1559 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1560  BinaryOperatorKind BOK) {
1561  D = getCanonicalDecl(D);
1562  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1563  assert(
1564  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1565  "Additional reduction info may be specified only for reduction items.");
1566  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1567  assert(ReductionData.ReductionRange.isInvalid() &&
1568  (getTopOfStack().Directive == OMPD_taskgroup ||
1569  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1570  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1571  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1572  "Additional reduction info may be specified only once for reduction "
1573  "items.");
1574  ReductionData.set(BOK, SR);
1575  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1576  if (!TaskgroupReductionRef) {
1577  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1578  SemaRef.Context.VoidPtrTy, ".task_red.");
1579  TaskgroupReductionRef =
1580  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1581  }
1582 }
1583 
1584 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1585  const Expr *ReductionRef) {
1586  D = getCanonicalDecl(D);
1587  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1588  assert(
1589  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1590  "Additional reduction info may be specified only for reduction items.");
1591  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1592  assert(ReductionData.ReductionRange.isInvalid() &&
1593  (getTopOfStack().Directive == OMPD_taskgroup ||
1594  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1595  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1596  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1597  "Additional reduction info may be specified only once for reduction "
1598  "items.");
1599  ReductionData.set(ReductionRef, SR);
1600  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1601  if (!TaskgroupReductionRef) {
1602  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1603  SemaRef.Context.VoidPtrTy, ".task_red.");
1604  TaskgroupReductionRef =
1605  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1606  }
1607 }
1608 
1609 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1610  const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1611  Expr *&TaskgroupDescriptor) const {
1612  D = getCanonicalDecl(D);
1613  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1614  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1615  const DSAInfo &Data = I->SharingMap.lookup(D);
1616  if (Data.Attributes != OMPC_reduction ||
1617  Data.Modifier != OMPC_REDUCTION_task)
1618  continue;
1619  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1620  if (!ReductionData.ReductionOp ||
1621  ReductionData.ReductionOp.is<const Expr *>())
1622  return DSAVarData();
1623  SR = ReductionData.ReductionRange;
1624  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1625  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1626  "expression for the descriptor is not "
1627  "set.");
1628  TaskgroupDescriptor = I->TaskgroupReductionRef;
1629  return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1630  Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1631  /*AppliedToPointee=*/false);
1632  }
1633  return DSAVarData();
1634 }
1635 
1636 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1637  const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1638  Expr *&TaskgroupDescriptor) const {
1639  D = getCanonicalDecl(D);
1640  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1641  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1642  const DSAInfo &Data = I->SharingMap.lookup(D);
1643  if (Data.Attributes != OMPC_reduction ||
1644  Data.Modifier != OMPC_REDUCTION_task)
1645  continue;
1646  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1647  if (!ReductionData.ReductionOp ||
1648  !ReductionData.ReductionOp.is<const Expr *>())
1649  return DSAVarData();
1650  SR = ReductionData.ReductionRange;
1651  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1652  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1653  "expression for the descriptor is not "
1654  "set.");
1655  TaskgroupDescriptor = I->TaskgroupReductionRef;
1656  return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1657  Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1658  /*AppliedToPointee=*/false);
1659  }
1660  return DSAVarData();
1661 }
1662 
1663 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1664  D = D->getCanonicalDecl();
1665  for (const_iterator E = end(); I != E; ++I) {
1666  if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1667  isOpenMPTargetExecutionDirective(I->Directive)) {
1668  if (I->CurScope) {
1669  Scope *TopScope = I->CurScope->getParent();
1670  Scope *CurScope = getCurScope();
1671  while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1672  CurScope = CurScope->getParent();
1673  return CurScope != TopScope;
1674  }
1675  for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1676  if (I->Context == DC)
1677  return true;
1678  return false;
1679  }
1680  }
1681  return false;
1682 }
1683 
1684 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1685  bool AcceptIfMutable = true,
1686  bool *IsClassType = nullptr) {
1687  ASTContext &Context = SemaRef.getASTContext();
1688  Type = Type.getNonReferenceType().getCanonicalType();
1689  bool IsConstant = Type.isConstant(Context);
1690  Type = Context.getBaseElementType(Type);
1691  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1693  : nullptr;
1694  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1695  if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1696  RD = CTD->getTemplatedDecl();
1697  if (IsClassType)
1698  *IsClassType = RD;
1699  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1700  RD->hasDefinition() && RD->hasMutableFields());
1701 }
1702 
1703 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1705  SourceLocation ELoc,
1706  bool AcceptIfMutable = true,
1707  bool ListItemNotVar = false) {
1708  ASTContext &Context = SemaRef.getASTContext();
1709  bool IsClassType;
1710  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1711  unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1712  : IsClassType ? diag::err_omp_const_not_mutable_variable
1713  : diag::err_omp_const_variable;
1714  SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1715  if (!ListItemNotVar && D) {
1716  const VarDecl *VD = dyn_cast<VarDecl>(D);
1717  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1719  SemaRef.Diag(D->getLocation(),
1720  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1721  << D;
1722  }
1723  return true;
1724  }
1725  return false;
1726 }
1727 
1728 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1729  bool FromParent) {
1730  D = getCanonicalDecl(D);
1731  DSAVarData DVar;
1732 
1733  auto *VD = dyn_cast<VarDecl>(D);
1734  auto TI = Threadprivates.find(D);
1735  if (TI != Threadprivates.end()) {
1736  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1737  DVar.CKind = OMPC_threadprivate;
1738  DVar.Modifier = TI->getSecond().Modifier;
1739  return DVar;
1740  }
1741  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1742  DVar.RefExpr = buildDeclRefExpr(
1743  SemaRef, VD, D->getType().getNonReferenceType(),
1744  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1745  DVar.CKind = OMPC_threadprivate;
1746  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1747  return DVar;
1748  }
1749  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1750  // in a Construct, C/C++, predetermined, p.1]
1751  // Variables appearing in threadprivate directives are threadprivate.
1752  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1753  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1754  SemaRef.getLangOpts().OpenMPUseTLS &&
1755  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1756  (VD && VD->getStorageClass() == SC_Register &&
1757  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1758  DVar.RefExpr = buildDeclRefExpr(
1759  SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1760  DVar.CKind = OMPC_threadprivate;
1761  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1762  return DVar;
1763  }
1764  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1765  VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1766  !isLoopControlVariable(D).first) {
1767  const_iterator IterTarget =
1768  std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1769  return isOpenMPTargetExecutionDirective(Data.Directive);
1770  });
1771  if (IterTarget != end()) {
1772  const_iterator ParentIterTarget = IterTarget + 1;
1773  for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1774  if (isOpenMPLocal(VD, Iter)) {
1775  DVar.RefExpr =
1776  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1777  D->getLocation());
1778  DVar.CKind = OMPC_threadprivate;
1779  return DVar;
1780  }
1781  }
1782  if (!isClauseParsingMode() || IterTarget != begin()) {
1783  auto DSAIter = IterTarget->SharingMap.find(D);
1784  if (DSAIter != IterTarget->SharingMap.end() &&
1785  isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1786  DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1787  DVar.CKind = OMPC_threadprivate;
1788  return DVar;
1789  }
1790  const_iterator End = end();
1791  if (!SemaRef.isOpenMPCapturedByRef(D,
1792  std::distance(ParentIterTarget, End),
1793  /*OpenMPCaptureLevel=*/0)) {
1794  DVar.RefExpr =
1795  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1796  IterTarget->ConstructLoc);
1797  DVar.CKind = OMPC_threadprivate;
1798  return DVar;
1799  }
1800  }
1801  }
1802  }
1803 
1804  if (isStackEmpty())
1805  // Not in OpenMP execution region and top scope was already checked.
1806  return DVar;
1807 
1808  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1809  // in a Construct, C/C++, predetermined, p.4]
1810  // Static data members are shared.
1811  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1812  // in a Construct, C/C++, predetermined, p.7]
1813  // Variables with static storage duration that are declared in a scope
1814  // inside the construct are shared.
1815  if (VD && VD->isStaticDataMember()) {
1816  // Check for explicitly specified attributes.
1817  const_iterator I = begin();
1818  const_iterator EndI = end();
1819  if (FromParent && I != EndI)
1820  ++I;
1821  if (I != EndI) {
1822  auto It = I->SharingMap.find(D);
1823  if (It != I->SharingMap.end()) {
1824  const DSAInfo &Data = It->getSecond();
1825  DVar.RefExpr = Data.RefExpr.getPointer();
1826  DVar.PrivateCopy = Data.PrivateCopy;
1827  DVar.CKind = Data.Attributes;
1828  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1829  DVar.DKind = I->Directive;
1830  DVar.Modifier = Data.Modifier;
1831  DVar.AppliedToPointee = Data.AppliedToPointee;
1832  return DVar;
1833  }
1834  }
1835 
1836  DVar.CKind = OMPC_shared;
1837  return DVar;
1838  }
1839 
1840  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1841  // The predetermined shared attribute for const-qualified types having no
1842  // mutable members was removed after OpenMP 3.1.
1843  if (SemaRef.LangOpts.OpenMP <= 31) {
1844  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1845  // in a Construct, C/C++, predetermined, p.6]
1846  // Variables with const qualified type having no mutable member are
1847  // shared.
1848  if (isConstNotMutableType(SemaRef, D->getType())) {
1849  // Variables with const-qualified type having no mutable member may be
1850  // listed in a firstprivate clause, even if they are static data members.
1851  DSAVarData DVarTemp = hasInnermostDSA(
1852  D,
1853  [](OpenMPClauseKind C, bool) {
1854  return C == OMPC_firstprivate || C == OMPC_shared;
1855  },
1856  MatchesAlways, FromParent);
1857  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1858  return DVarTemp;
1859 
1860  DVar.CKind = OMPC_shared;
1861  return DVar;
1862  }
1863  }
1864 
1865  // Explicitly specified attributes and local variables with predetermined
1866  // attributes.
1867  const_iterator I = begin();
1868  const_iterator EndI = end();
1869  if (FromParent && I != EndI)
1870  ++I;
1871  if (I == EndI)
1872  return DVar;
1873  auto It = I->SharingMap.find(D);
1874  if (It != I->SharingMap.end()) {
1875  const DSAInfo &Data = It->getSecond();
1876  DVar.RefExpr = Data.RefExpr.getPointer();
1877  DVar.PrivateCopy = Data.PrivateCopy;
1878  DVar.CKind = Data.Attributes;
1879  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1880  DVar.DKind = I->Directive;
1881  DVar.Modifier = Data.Modifier;
1882  DVar.AppliedToPointee = Data.AppliedToPointee;
1883  }
1884 
1885  return DVar;
1886 }
1887 
1888 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1889  bool FromParent) const {
1890  if (isStackEmpty()) {
1891  const_iterator I;
1892  return getDSA(I, D);
1893  }
1894  D = getCanonicalDecl(D);
1895  const_iterator StartI = begin();
1896  const_iterator EndI = end();
1897  if (FromParent && StartI != EndI)
1898  ++StartI;
1899  return getDSA(StartI, D);
1900 }
1901 
1902 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1903  unsigned Level) const {
1904  if (getStackSize() <= Level)
1905  return DSAVarData();
1906  D = getCanonicalDecl(D);
1907  const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1908  return getDSA(StartI, D);
1909 }
1910 
1911 const DSAStackTy::DSAVarData
1912 DSAStackTy::hasDSA(ValueDecl *D,
1913  const llvm::function_ref<bool(OpenMPClauseKind, bool,
1914  DefaultDataSharingAttributes)>
1915  CPred,
1916  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1917  bool FromParent) const {
1918  if (isStackEmpty())
1919  return {};
1920  D = getCanonicalDecl(D);
1921  const_iterator I = begin();
1922  const_iterator EndI = end();
1923  if (FromParent && I != EndI)
1924  ++I;
1925  for (; I != EndI; ++I) {
1926  if (!DPred(I->Directive) &&
1927  !isImplicitOrExplicitTaskingRegion(I->Directive))
1928  continue;
1929  const_iterator NewI = I;
1930  DSAVarData DVar = getDSA(NewI, D);
1931  if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1932  return DVar;
1933  }
1934  return {};
1935 }
1936 
1937 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1938  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1939  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1940  bool FromParent) const {
1941  if (isStackEmpty())
1942  return {};
1943  D = getCanonicalDecl(D);
1944  const_iterator StartI = begin();
1945  const_iterator EndI = end();
1946  if (FromParent && StartI != EndI)
1947  ++StartI;
1948  if (StartI == EndI || !DPred(StartI->Directive))
1949  return {};
1950  const_iterator NewI = StartI;
1951  DSAVarData DVar = getDSA(NewI, D);
1952  return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1953  ? DVar
1954  : DSAVarData();
1955 }
1956 
1957 bool DSAStackTy::hasExplicitDSA(
1958  const ValueDecl *D,
1959  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1960  unsigned Level, bool NotLastprivate) const {
1961  if (getStackSize() <= Level)
1962  return false;
1963  D = getCanonicalDecl(D);
1964  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1965  auto I = StackElem.SharingMap.find(D);
1966  if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1967  CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1968  (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1969  return true;
1970  // Check predetermined rules for the loop control variables.
1971  auto LI = StackElem.LCVMap.find(D);
1972  if (LI != StackElem.LCVMap.end())
1973  return CPred(OMPC_private, /*AppliedToPointee=*/false);
1974  return false;
1975 }
1976 
1977 bool DSAStackTy::hasExplicitDirective(
1978  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1979  unsigned Level) const {
1980  if (getStackSize() <= Level)
1981  return false;
1982  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1983  return DPred(StackElem.Directive);
1984 }
1985 
1986 bool DSAStackTy::hasDirective(
1987  const llvm::function_ref<bool(OpenMPDirectiveKind,
1989  DPred,
1990  bool FromParent) const {
1991  // We look only in the enclosing region.
1992  size_t Skip = FromParent ? 2 : 1;
1993  for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1994  I != E; ++I) {
1995  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1996  return true;
1997  }
1998  return false;
1999 }
2000 
2001 void Sema::InitDataSharingAttributesStack() {
2002  VarDataSharingAttributesStack = new DSAStackTy(*this);
2003 }
2004 
2005 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2006 
2007 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2008 
2009 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2010  DSAStack->popFunction(OldFSI);
2011 }
2012 
2014  assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
2015  "Expected OpenMP device compilation.");
2017 }
2018 
2019 namespace {
2020 /// Status of the function emission on the host/device.
2021 enum class FunctionEmissionStatus {
2022  Emitted,
2023  Discarded,
2024  Unknown,
2025 };
2026 } // anonymous namespace
2027 
2029  unsigned DiagID,
2030  FunctionDecl *FD) {
2031  assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
2032  "Expected OpenMP device compilation.");
2033 
2034  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2035  if (FD) {
2036  FunctionEmissionStatus FES = getEmissionStatus(FD);
2037  switch (FES) {
2038  case FunctionEmissionStatus::Emitted:
2039  Kind = SemaDiagnosticBuilder::K_Immediate;
2040  break;
2042  // TODO: We should always delay diagnostics here in case a target
2043  // region is in a function we do not emit. However, as the
2044  // current diagnostics are associated with the function containing
2045  // the target region and we do not emit that one, we would miss out
2046  // on diagnostics for the target region itself. We need to anchor
2047  // the diagnostics with the new generated function *or* ensure we
2048  // emit diagnostics associated with the surrounding function.
2050  ? SemaDiagnosticBuilder::K_Deferred
2051  : SemaDiagnosticBuilder::K_Immediate;
2052  break;
2053  case FunctionEmissionStatus::TemplateDiscarded:
2054  case FunctionEmissionStatus::OMPDiscarded:
2055  Kind = SemaDiagnosticBuilder::K_Nop;
2056  break;
2057  case FunctionEmissionStatus::CUDADiscarded:
2058  llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2059  break;
2060  }
2061  }
2062 
2063  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2064 }
2065 
2067  unsigned DiagID,
2068  FunctionDecl *FD) {
2069  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
2070  "Expected OpenMP host compilation.");
2071 
2072  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2073  if (FD) {
2074  FunctionEmissionStatus FES = getEmissionStatus(FD);
2075  switch (FES) {
2076  case FunctionEmissionStatus::Emitted:
2077  Kind = SemaDiagnosticBuilder::K_Immediate;
2078  break;
2080  Kind = SemaDiagnosticBuilder::K_Deferred;
2081  break;
2082  case FunctionEmissionStatus::TemplateDiscarded:
2083  case FunctionEmissionStatus::OMPDiscarded:
2084  case FunctionEmissionStatus::CUDADiscarded:
2085  Kind = SemaDiagnosticBuilder::K_Nop;
2086  break;
2087  }
2088  }
2089 
2090  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2091 }
2092 
2095  if (LO.OpenMP <= 45) {
2096  if (VD->getType().getNonReferenceType()->isScalarType())
2097  return OMPC_DEFAULTMAP_scalar;
2098  return OMPC_DEFAULTMAP_aggregate;
2099  }
2101  return OMPC_DEFAULTMAP_pointer;
2102  if (VD->getType().getNonReferenceType()->isScalarType())
2103  return OMPC_DEFAULTMAP_scalar;
2104  return OMPC_DEFAULTMAP_aggregate;
2105 }
2106 
2108  unsigned OpenMPCaptureLevel) const {
2109  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2110 
2111  ASTContext &Ctx = getASTContext();
2112  bool IsByRef = true;
2113 
2114  // Find the directive that is associated with the provided scope.
2115  D = cast<ValueDecl>(D->getCanonicalDecl());
2116  QualType Ty = D->getType();
2117 
2118  bool IsVariableUsedInMapClause = false;
2119  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2120  // This table summarizes how a given variable should be passed to the device
2121  // given its type and the clauses where it appears. This table is based on
2122  // the description in OpenMP 4.5 [2.10.4, target Construct] and
2123  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2124  //
2125  // =========================================================================
2126  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2127  // | |(tofrom:scalar)| | pvt | |has_dv_adr| |
2128  // =========================================================================
2129  // | scl | | | | - | | bycopy|
2130  // | scl | | - | x | - | - | bycopy|
2131  // | scl | | x | - | - | - | null |
2132  // | scl | x | | | - | | byref |
2133  // | scl | x | - | x | - | - | bycopy|
2134  // | scl | x | x | - | - | - | null |
2135  // | scl | | - | - | - | x | byref |
2136  // | scl | x | - | - | - | x | byref |
2137  //
2138  // | agg | n.a. | | | - | | byref |
2139  // | agg | n.a. | - | x | - | - | byref |
2140  // | agg | n.a. | x | - | - | - | null |
2141  // | agg | n.a. | - | - | - | x | byref |
2142  // | agg | n.a. | - | - | - | x[] | byref |
2143  //
2144  // | ptr | n.a. | | | - | | bycopy|
2145  // | ptr | n.a. | - | x | - | - | bycopy|
2146  // | ptr | n.a. | x | - | - | - | null |
2147  // | ptr | n.a. | - | - | - | x | byref |
2148  // | ptr | n.a. | - | - | - | x[] | bycopy|
2149  // | ptr | n.a. | - | - | x | | bycopy|
2150  // | ptr | n.a. | - | - | x | x | bycopy|
2151  // | ptr | n.a. | - | - | x | x[] | bycopy|
2152  // =========================================================================
2153  // Legend:
2154  // scl - scalar
2155  // ptr - pointer
2156  // agg - aggregate
2157  // x - applies
2158  // - - invalid in this combination
2159  // [] - mapped with an array section
2160  // byref - should be mapped by reference
2161  // byval - should be mapped by value
2162  // null - initialize a local variable to null on the device
2163  //
2164  // Observations:
2165  // - All scalar declarations that show up in a map clause have to be passed
2166  // by reference, because they may have been mapped in the enclosing data
2167  // environment.
2168  // - If the scalar value does not fit the size of uintptr, it has to be
2169  // passed by reference, regardless the result in the table above.
2170  // - For pointers mapped by value that have either an implicit map or an
2171  // array section, the runtime library may pass the NULL value to the
2172  // device instead of the value passed to it by the compiler.
2173 
2174  if (Ty->isReferenceType())
2175  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2176 
2177  // Locate map clauses and see if the variable being captured is referred to
2178  // in any of those clauses. Here we only care about variables, not fields,
2179  // because fields are part of aggregates.
2180  bool IsVariableAssociatedWithSection = false;
2181 
2182  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2183  D, Level,
2184  [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2186  MapExprComponents,
2187  OpenMPClauseKind WhereFoundClauseKind) {
2188  // Both map and has_device_addr clauses information influences how a
2189  // variable is captured. E.g. is_device_ptr does not require changing
2190  // the default behavior.
2191  if (WhereFoundClauseKind != OMPC_map &&
2192  WhereFoundClauseKind != OMPC_has_device_addr)
2193  return false;
2194 
2195  auto EI = MapExprComponents.rbegin();
2196  auto EE = MapExprComponents.rend();
2197 
2198  assert(EI != EE && "Invalid map expression!");
2199 
2200  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2201  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2202 
2203  ++EI;
2204  if (EI == EE)
2205  return false;
2206 
2207  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2208  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2209  isa<MemberExpr>(EI->getAssociatedExpression()) ||
2210  isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2211  IsVariableAssociatedWithSection = true;
2212  // There is nothing more we need to know about this variable.
2213  return true;
2214  }
2215 
2216  // Keep looking for more map info.
2217  return false;
2218  });
2219 
2220  if (IsVariableUsedInMapClause) {
2221  // If variable is identified in a map clause it is always captured by
2222  // reference except if it is a pointer that is dereferenced somehow.
2223  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2224  } else {
2225  // By default, all the data that has a scalar type is mapped by copy
2226  // (except for reduction variables).
2227  // Defaultmap scalar is mutual exclusive to defaultmap pointer
2228  IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2229  !Ty->isAnyPointerType()) ||
2230  !Ty->isScalarType() ||
2231  DSAStack->isDefaultmapCapturedByRef(
2232  Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2233  DSAStack->hasExplicitDSA(
2234  D,
2235  [](OpenMPClauseKind K, bool AppliedToPointee) {
2236  return K == OMPC_reduction && !AppliedToPointee;
2237  },
2238  Level);
2239  }
2240  }
2241 
2242  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2243  IsByRef =
2244  ((IsVariableUsedInMapClause &&
2245  DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2246  OMPD_target) ||
2247  !(DSAStack->hasExplicitDSA(
2248  D,
2249  [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2250  return K == OMPC_firstprivate ||
2251  (K == OMPC_reduction && AppliedToPointee);
2252  },
2253  Level, /*NotLastprivate=*/true) ||
2254  DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2255  // If the variable is artificial and must be captured by value - try to
2256  // capture by value.
2257  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2258  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2259  // If the variable is implicitly firstprivate and scalar - capture by
2260  // copy
2261  !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2262  DSAStack->getDefaultDSA() == DSA_private) &&
2263  !DSAStack->hasExplicitDSA(
2264  D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2265  Level) &&
2266  !DSAStack->isLoopControlVariable(D, Level).first);
2267  }
2268 
2269  // When passing data by copy, we need to make sure it fits the uintptr size
2270  // and alignment, because the runtime library only deals with uintptr types.
2271  // If it does not fit the uintptr size, we need to pass the data by reference
2272  // instead.
2273  if (!IsByRef &&
2274  (Ctx.getTypeSizeInChars(Ty) >
2275  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2276  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2277  IsByRef = true;
2278  }
2279 
2280  return IsByRef;
2281 }
2282 
2283 unsigned Sema::getOpenMPNestingLevel() const {
2284  assert(getLangOpts().OpenMP);
2285  return DSAStack->getNestingLevel();
2286 }
2287 
2289  return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2290  DSAStack->isUntiedRegion();
2291 }
2292 
2294  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2295  !DSAStack->isClauseParsingMode()) ||
2296  DSAStack->hasDirective(
2298  SourceLocation) -> bool {
2300  },
2301  false);
2302 }
2303 
2305  // Only rebuild for Field.
2306  if (!dyn_cast<FieldDecl>(D))
2307  return false;
2308  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2309  D,
2310  [](OpenMPClauseKind C, bool AppliedToPointee,
2311  DefaultDataSharingAttributes DefaultAttr) {
2312  return isOpenMPPrivate(C) && !AppliedToPointee &&
2313  (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2314  },
2315  [](OpenMPDirectiveKind) { return true; },
2316  DSAStack->isClauseParsingMode());
2317  if (DVarPrivate.CKind != OMPC_unknown)
2318  return true;
2319  return false;
2320 }
2321 
2323  Expr *CaptureExpr, bool WithInit,
2324  DeclContext *CurContext,
2325  bool AsExpression);
2326 
2328  unsigned StopAt) {
2329  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2330  D = getCanonicalDecl(D);
2331 
2332  auto *VD = dyn_cast<VarDecl>(D);
2333  // Do not capture constexpr variables.
2334  if (VD && VD->isConstexpr())
2335  return nullptr;
2336 
2337  // If we want to determine whether the variable should be captured from the
2338  // perspective of the current capturing scope, and we've already left all the
2339  // capturing scopes of the top directive on the stack, check from the
2340  // perspective of its parent directive (if any) instead.
2341  DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2342  *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2343 
2344  // If we are attempting to capture a global variable in a directive with
2345  // 'target' we return true so that this global is also mapped to the device.
2346  //
2347  if (VD && !VD->hasLocalStorage() &&
2348  (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2349  if (isInOpenMPTargetExecutionDirective()) {
2350  DSAStackTy::DSAVarData DVarTop =
2351  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2352  if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2353  return VD;
2354  // If the declaration is enclosed in a 'declare target' directive,
2355  // then it should not be captured.
2356  //
2357  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2358  return nullptr;
2359  CapturedRegionScopeInfo *CSI = nullptr;
2360  for (FunctionScopeInfo *FSI : llvm::drop_begin(
2361  llvm::reverse(FunctionScopes),
2362  CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2363  if (!isa<CapturingScopeInfo>(FSI))
2364  return nullptr;
2365  if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2366  if (RSI->CapRegionKind == CR_OpenMP) {
2367  CSI = RSI;
2368  break;
2369  }
2370  }
2371  assert(CSI && "Failed to find CapturedRegionScopeInfo");
2373  getOpenMPCaptureRegions(Regions,
2374  DSAStack->getDirective(CSI->OpenMPLevel));
2375  if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2376  return VD;
2377  }
2378  if (isInOpenMPDeclareTargetContext()) {
2379  // Try to mark variable as declare target if it is used in capturing
2380  // regions.
2381  if (LangOpts.OpenMP <= 45 &&
2382  !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2383  checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2384  return nullptr;
2385  }
2386  }
2387 
2388  if (CheckScopeInfo) {
2389  bool OpenMPFound = false;
2390  for (unsigned I = StopAt + 1; I > 0; --I) {
2391  FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2392  if (!isa<CapturingScopeInfo>(FSI))
2393  return nullptr;
2394  if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2395  if (RSI->CapRegionKind == CR_OpenMP) {
2396  OpenMPFound = true;
2397  break;
2398  }
2399  }
2400  if (!OpenMPFound)
2401  return nullptr;
2402  }
2403 
2404  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2405  (!DSAStack->isClauseParsingMode() ||
2406  DSAStack->getParentDirective() != OMPD_unknown)) {
2407  auto &&Info = DSAStack->isLoopControlVariable(D);
2408  if (Info.first ||
2409  (VD && VD->hasLocalStorage() &&
2410  isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2411  (VD && DSAStack->isForceVarCapturing()))
2412  return VD ? VD : Info.second;
2413  DSAStackTy::DSAVarData DVarTop =
2414  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2415  if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2416  (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2417  return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2418  // Threadprivate variables must not be captured.
2419  if (isOpenMPThreadPrivate(DVarTop.CKind))
2420  return nullptr;
2421  // The variable is not private or it is the variable in the directive with
2422  // default(none) clause and not used in any clause.
2423  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2424  D,
2425  [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2426  return isOpenMPPrivate(C) && !AppliedToPointee;
2427  },
2428  [](OpenMPDirectiveKind) { return true; },
2429  DSAStack->isClauseParsingMode());
2430  // Global shared must not be captured.
2431  if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2432  ((DSAStack->getDefaultDSA() != DSA_none &&
2433  DSAStack->getDefaultDSA() != DSA_private &&
2434  DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2435  DVarTop.CKind == OMPC_shared))
2436  return nullptr;
2437  auto *FD = dyn_cast<FieldDecl>(D);
2438  if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2439  !DVarPrivate.PrivateCopy) {
2440  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2441  D,
2442  [](OpenMPClauseKind C, bool AppliedToPointee,
2443  DefaultDataSharingAttributes DefaultAttr) {
2444  return isOpenMPPrivate(C) && !AppliedToPointee &&
2445  (DefaultAttr == DSA_firstprivate ||
2446  DefaultAttr == DSA_private);
2447  },
2448  [](OpenMPDirectiveKind) { return true; },
2449  DSAStack->isClauseParsingMode());
2450  if (DVarPrivate.CKind == OMPC_unknown)
2451  return nullptr;
2452 
2453  VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2454  if (VD)
2455  return VD;
2456  if (getCurrentThisType().isNull())
2457  return nullptr;
2458  Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2459  /*IsImplicit=*/true);
2460  const CXXScopeSpec CS = CXXScopeSpec();
2461  Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2463  DeclAccessPair::make(FD, FD->getAccess()),
2464  /*HadMultipleCandidates=*/false,
2465  DeclarationNameInfo(), FD->getType(),
2468  *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2469  CurContext->getParent(), /*AsExpression=*/false);
2470  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2471  *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2472  VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2473  DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2474  return VD;
2475  }
2476  if (DVarPrivate.CKind != OMPC_unknown ||
2477  (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2478  DSAStack->getDefaultDSA() == DSA_private ||
2479  DSAStack->getDefaultDSA() == DSA_firstprivate)))
2480  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2481  }
2482  return nullptr;
2483 }
2484 
2485 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2486  unsigned Level) const {
2487  FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2488 }
2489 
2491  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2492  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2493  DSAStack->loopInit();
2494 }
2495 
2497  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2498  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2499  DSAStack->resetPossibleLoopCounter();
2500  DSAStack->loopStart();
2501  }
2502 }
2503 
2505  unsigned CapLevel) const {
2506  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2507  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2508  (!DSAStack->isClauseParsingMode() ||
2509  DSAStack->getParentDirective() != OMPD_unknown)) {
2510  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2511  D,
2512  [](OpenMPClauseKind C, bool AppliedToPointee,
2513  DefaultDataSharingAttributes DefaultAttr) {
2514  return isOpenMPPrivate(C) && !AppliedToPointee &&
2515  DefaultAttr == DSA_private;
2516  },
2517  [](OpenMPDirectiveKind) { return true; },
2518  DSAStack->isClauseParsingMode());
2519  if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2520  DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2521  !DSAStack->isLoopControlVariable(D).first)
2522  return OMPC_private;
2523  }
2524  if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2525  bool IsTriviallyCopyable =
2527  !D->getType()
2529  .getCanonicalType()
2530  ->getAsCXXRecordDecl();
2531  OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2532  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2533  getOpenMPCaptureRegions(CaptureRegions, DKind);
2534  if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2535  (IsTriviallyCopyable ||
2536  !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2537  if (DSAStack->hasExplicitDSA(
2538  D,
2539  [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2540  Level, /*NotLastprivate=*/true))
2541  return OMPC_firstprivate;
2542  DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2543  if (DVar.CKind != OMPC_shared &&
2544  !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2545  DSAStack->addImplicitTaskFirstprivate(Level, D);
2546  return OMPC_firstprivate;
2547  }
2548  }
2549  }
2550  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2551  if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2552  DSAStack->resetPossibleLoopCounter(D);
2553  DSAStack->loopStart();
2554  return OMPC_private;
2555  }
2556  if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2557  DSAStack->isLoopControlVariable(D).first) &&
2558  !DSAStack->hasExplicitDSA(
2559  D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2560  Level) &&
2561  !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2562  return OMPC_private;
2563  }
2564  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2565  if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2566  DSAStack->isForceVarCapturing() &&
2567  !DSAStack->hasExplicitDSA(
2568  D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2569  Level))
2570  return OMPC_private;
2571  }
2572  // User-defined allocators are private since they must be defined in the
2573  // context of target region.
2574  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2575  DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2576  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2577  DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2578  return OMPC_private;
2579  return (DSAStack->hasExplicitDSA(
2580  D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2581  Level) ||
2582  (DSAStack->isClauseParsingMode() &&
2583  DSAStack->getClauseParsingMode() == OMPC_private) ||
2584  // Consider taskgroup reduction descriptor variable a private
2585  // to avoid possible capture in the region.
2586  (DSAStack->hasExplicitDirective(
2587  [](OpenMPDirectiveKind K) {
2588  return K == OMPD_taskgroup ||
2589  ((isOpenMPParallelDirective(K) ||
2590  isOpenMPWorksharingDirective(K)) &&
2591  !isOpenMPSimdDirective(K));
2592  },
2593  Level) &&
2594  DSAStack->isTaskgroupReductionRef(D, Level)))
2595  ? OMPC_private
2596  : OMPC_unknown;
2597 }
2598 
2600  unsigned Level) {
2601  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2602  D = getCanonicalDecl(D);
2603  OpenMPClauseKind OMPC = OMPC_unknown;
2604  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2605  const unsigned NewLevel = I - 1;
2606  if (DSAStack->hasExplicitDSA(
2607  D,
2608  [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2609  if (isOpenMPPrivate(K) && !AppliedToPointee) {
2610  OMPC = K;
2611  return true;
2612  }
2613  return false;
2614  },
2615  NewLevel))
2616  break;
2617  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2618  D, NewLevel,
2620  OpenMPClauseKind) { return true; })) {
2621  OMPC = OMPC_map;
2622  break;
2623  }
2624  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2625  NewLevel)) {
2626  OMPC = OMPC_map;
2627  if (DSAStack->mustBeFirstprivateAtLevel(
2628  NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2629  OMPC = OMPC_firstprivate;
2630  break;
2631  }
2632  }
2633  if (OMPC != OMPC_unknown)
2634  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2635 }
2636 
2638  unsigned CaptureLevel) const {
2639  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2640  // Return true if the current level is no longer enclosed in a target region.
2641 
2643  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2644  const auto *VD = dyn_cast<VarDecl>(D);
2645  return VD && !VD->hasLocalStorage() &&
2646  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2647  Level) &&
2648  Regions[CaptureLevel] != OMPD_task;
2649 }
2650 
2652  unsigned CaptureLevel) const {
2653  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2654  // Return true if the current level is no longer enclosed in a target region.
2655 
2656  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2657  if (!VD->hasLocalStorage()) {
2659  return true;
2660  DSAStackTy::DSAVarData TopDVar =
2661  DSAStack->getTopDSA(D, /*FromParent=*/false);
2662  unsigned NumLevels =
2663  getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2664  if (Level == 0)
2665  // non-file scope static variale with default(firstprivate)
2666  // should be gloabal captured.
2667  return (NumLevels == CaptureLevel + 1 &&
2668  (TopDVar.CKind != OMPC_shared ||
2669  DSAStack->getDefaultDSA() == DSA_firstprivate));
2670  do {
2671  --Level;
2672  DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2673  if (DVar.CKind != OMPC_shared)
2674  return true;
2675  } while (Level > 0);
2676  }
2677  }
2678  return true;
2679 }
2680 
2681 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2682 
2684  OMPTraitInfo &TI) {
2685  OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2686 }
2687 
2689  assert(isInOpenMPDeclareVariantScope() &&
2690  "Not in OpenMP declare variant scope!");
2691 
2692  OMPDeclareVariantScopes.pop_back();
2693 }
2694 
2696  const FunctionDecl *Callee,
2697  SourceLocation Loc) {
2698  assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2699  std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2700  OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2701  // Ignore host functions during device analyzis.
2702  if (LangOpts.OpenMPIsDevice &&
2703  (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2704  return;
2705  // Ignore nohost functions during host analyzis.
2706  if (!LangOpts.OpenMPIsDevice && DevTy &&
2707  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2708  return;
2709  const FunctionDecl *FD = Callee->getMostRecentDecl();
2710  DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2711  if (LangOpts.OpenMPIsDevice && DevTy &&
2712  *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2713  // Diagnose host function called during device codegen.
2714  StringRef HostDevTy =
2715  getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2716  Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2717  Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2718  diag::note_omp_marked_device_type_here)
2719  << HostDevTy;
2720  return;
2721  }
2722  if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2723  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2724  // In OpenMP 5.2 or later, if the function has a host variant then allow
2725  // that to be called instead
2726  auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2727  for (OMPDeclareVariantAttr *A :
2728  Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2729  auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2730  auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2731  std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2732  OMPDeclareTargetDeclAttr::getDeviceType(
2733  VariantFD->getMostRecentDecl());
2734  if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2735  return true;
2736  }
2737  return false;
2738  };
2739  if (getLangOpts().OpenMP >= 52 &&
2740  Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2741  return;
2742  // Diagnose nohost function called during host codegen.
2743  StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2744  OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2745  Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2746  Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2747  diag::note_omp_marked_device_type_here)
2748  << NoHostDevTy;
2749  }
2750 }
2751 
2753  const DeclarationNameInfo &DirName,
2754  Scope *CurScope, SourceLocation Loc) {
2755  DSAStack->push(DKind, DirName, CurScope, Loc);
2758 }
2759 
2761  DSAStack->setClauseParsingMode(K);
2762 }
2763 
2765  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2767 }
2768 
2769 static std::pair<ValueDecl *, bool>
2770 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2771  SourceRange &ERange, bool AllowArraySection = false,
2772  StringRef DiagType = "");
2773 
2774 /// Check consistency of the reduction clauses.
2775 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2776  ArrayRef<OMPClause *> Clauses) {
2777  bool InscanFound = false;
2778  SourceLocation InscanLoc;
2779  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2780  // A reduction clause without the inscan reduction-modifier may not appear on
2781  // a construct on which a reduction clause with the inscan reduction-modifier
2782  // appears.
2783  for (OMPClause *C : Clauses) {
2784  if (C->getClauseKind() != OMPC_reduction)
2785  continue;
2786  auto *RC = cast<OMPReductionClause>(C);
2787  if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2788  InscanFound = true;
2789  InscanLoc = RC->getModifierLoc();
2790  continue;
2791  }
2792  if (RC->getModifier() == OMPC_REDUCTION_task) {
2793  // OpenMP 5.0, 2.19.5.4 reduction Clause.
2794  // A reduction clause with the task reduction-modifier may only appear on
2795  // a parallel construct, a worksharing construct or a combined or
2796  // composite construct for which any of the aforementioned constructs is a
2797  // constituent construct and simd or loop are not constituent constructs.
2798  OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2799  if (!(isOpenMPParallelDirective(CurDir) ||
2800  isOpenMPWorksharingDirective(CurDir)) ||
2801  isOpenMPSimdDirective(CurDir))
2802  S.Diag(RC->getModifierLoc(),
2803  diag::err_omp_reduction_task_not_parallel_or_worksharing);
2804  continue;
2805  }
2806  }
2807  if (InscanFound) {
2808  for (OMPClause *C : Clauses) {
2809  if (C->getClauseKind() != OMPC_reduction)
2810  continue;
2811  auto *RC = cast<OMPReductionClause>(C);
2812  if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2813  S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2814  ? RC->getBeginLoc()
2815  : RC->getModifierLoc(),
2816  diag::err_omp_inscan_reduction_expected);
2817  S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2818  continue;
2819  }
2820  for (Expr *Ref : RC->varlists()) {
2821  assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2822  SourceLocation ELoc;
2823  SourceRange ERange;
2824  Expr *SimpleRefExpr = Ref;
2825  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2826  /*AllowArraySection=*/true);
2827  ValueDecl *D = Res.first;
2828  if (!D)
2829  continue;
2830  if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2831  S.Diag(Ref->getExprLoc(),
2832  diag::err_omp_reduction_not_inclusive_exclusive)
2833  << Ref->getSourceRange();
2834  }
2835  }
2836  }
2837  }
2838 }
2839 
2840 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2841  ArrayRef<OMPClause *> Clauses);
2842 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2843  bool WithInit);
2844 
2845 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2846  const ValueDecl *D,
2847  const DSAStackTy::DSAVarData &DVar,
2848  bool IsLoopIterVar = false);
2849 
2850 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2851  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2852  // A variable of class type (or array thereof) that appears in a lastprivate
2853  // clause requires an accessible, unambiguous default constructor for the
2854  // class type, unless the list item is also specified in a firstprivate
2855  // clause.
2856  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2857  for (OMPClause *C : D->clauses()) {
2858  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2859  SmallVector<Expr *, 8> PrivateCopies;
2860  for (Expr *DE : Clause->varlists()) {
2861  if (DE->isValueDependent() || DE->isTypeDependent()) {
2862  PrivateCopies.push_back(nullptr);
2863  continue;
2864  }
2865  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2866  auto *VD = cast<VarDecl>(DRE->getDecl());
2868  const DSAStackTy::DSAVarData DVar =
2869  DSAStack->getTopDSA(VD, /*FromParent=*/false);
2870  if (DVar.CKind == OMPC_lastprivate) {
2871  // Generate helper private variable and initialize it with the
2872  // default value. The address of the original variable is replaced
2873  // by the address of the new private variable in CodeGen. This new
2874  // variable is not added to IdResolver, so the code in the OpenMP
2875  // region uses original variable for proper diagnostics.
2876  VarDecl *VDPrivate = buildVarDecl(
2877  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2878  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2879  ActOnUninitializedDecl(VDPrivate);
2880  if (VDPrivate->isInvalidDecl()) {
2881  PrivateCopies.push_back(nullptr);
2882  continue;
2883  }
2884  PrivateCopies.push_back(buildDeclRefExpr(
2885  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2886  } else {
2887  // The variable is also a firstprivate, so initialization sequence
2888  // for private copy is generated already.
2889  PrivateCopies.push_back(nullptr);
2890  }
2891  }
2892  Clause->setPrivateCopies(PrivateCopies);
2893  continue;
2894  }
2895  // Finalize nontemporal clause by handling private copies, if any.
2896  if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2897  SmallVector<Expr *, 8> PrivateRefs;
2898  for (Expr *RefExpr : Clause->varlists()) {
2899  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2900  SourceLocation ELoc;
2901  SourceRange ERange;
2902  Expr *SimpleRefExpr = RefExpr;
2903  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2904  if (Res.second)
2905  // It will be analyzed later.
2906  PrivateRefs.push_back(RefExpr);
2907  ValueDecl *D = Res.first;
2908  if (!D)
2909  continue;
2910 
2911  const DSAStackTy::DSAVarData DVar =
2912  DSAStack->getTopDSA(D, /*FromParent=*/false);
2913  PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2914  : SimpleRefExpr);
2915  }
2916  Clause->setPrivateRefs(PrivateRefs);
2917  continue;
2918  }
2919  if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2920  for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2921  OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2922  auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2923  if (!DRE)
2924  continue;
2925  ValueDecl *VD = DRE->getDecl();
2926  if (!VD || !isa<VarDecl>(VD))
2927  continue;
2928  DSAStackTy::DSAVarData DVar =
2929  DSAStack->getTopDSA(VD, /*FromParent=*/false);
2930  // OpenMP [2.12.5, target Construct]
2931  // Memory allocators that appear in a uses_allocators clause cannot
2932  // appear in other data-sharing attribute clauses or data-mapping
2933  // attribute clauses in the same construct.
2934  Expr *MapExpr = nullptr;
2935  if (DVar.RefExpr ||
2936  DSAStack->checkMappableExprComponentListsForDecl(
2937  VD, /*CurrentRegionOnly=*/true,
2938  [VD, &MapExpr](
2940  MapExprComponents,
2941  OpenMPClauseKind C) {
2942  auto MI = MapExprComponents.rbegin();
2943  auto ME = MapExprComponents.rend();
2944  if (MI != ME &&
2945  MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2946  VD->getCanonicalDecl()) {
2947  MapExpr = MI->getAssociatedExpression();
2948  return true;
2949  }
2950  return false;
2951  })) {
2952  Diag(D.Allocator->getExprLoc(),
2953  diag::err_omp_allocator_used_in_clauses)
2954  << D.Allocator->getSourceRange();
2955  if (DVar.RefExpr)
2956  reportOriginalDsa(*this, DSAStack, VD, DVar);
2957  else
2958  Diag(MapExpr->getExprLoc(), diag::note_used_here)
2959  << MapExpr->getSourceRange();
2960  }
2961  }
2962  continue;
2963  }
2964  }
2965  // Check allocate clauses.
2967  checkAllocateClauses(*this, DSAStack, D->clauses());
2968  checkReductionClauses(*this, DSAStack, D->clauses());
2969  }
2970 
2971  DSAStack->pop();
2972  DiscardCleanupsInEvaluationContext();
2973  PopExpressionEvaluationContext();
2974 }
2975 
2976 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2977  Expr *NumIterations, Sema &SemaRef,
2978  Scope *S, DSAStackTy *Stack);
2979 
2980 namespace {
2981 
2982 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2983 private:
2984  Sema &SemaRef;
2985 
2986 public:
2987  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2988  bool ValidateCandidate(const TypoCorrection &Candidate) override {
2989  NamedDecl *ND = Candidate.getCorrectionDecl();
2990  if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2991  return VD->hasGlobalStorage() &&
2992  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2993  SemaRef.getCurScope());
2994  }
2995  return false;
2996  }
2997 
2998  std::unique_ptr<CorrectionCandidateCallback> clone() override {
2999  return std::make_unique<VarDeclFilterCCC>(*this);
3000  }
3001 };
3002 
3003 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3004 private:
3005  Sema &SemaRef;
3006 
3007 public:
3008  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3009  bool ValidateCandidate(const TypoCorrection &Candidate) override {
3010  NamedDecl *ND = Candidate.getCorrectionDecl();
3011  if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3012  isa<FunctionDecl>(ND))) {
3013  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3014  SemaRef.getCurScope());
3015  }
3016  return false;
3017  }
3018 
3019  std::unique_ptr<CorrectionCandidateCallback> clone() override {
3020  return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3021  }
3022 };
3023 
3024 } // namespace
3025 
3026 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3027  CXXScopeSpec &ScopeSpec,
3028  const DeclarationNameInfo &Id,
3030  LookupResult Lookup(*this, Id, LookupOrdinaryName);
3031  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3032 
3033  if (Lookup.isAmbiguous())
3034  return ExprError();
3035 
3036  VarDecl *VD;
3037  if (!Lookup.isSingleResult()) {
3038  VarDeclFilterCCC CCC(*this);
3039  if (TypoCorrection Corrected =
3040  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3041  CTK_ErrorRecovery)) {
3042  diagnoseTypo(Corrected,
3043  PDiag(Lookup.empty()
3044  ? diag::err_undeclared_var_use_suggest
3045  : diag::err_omp_expected_var_arg_suggest)
3046  << Id.getName());
3047  VD = Corrected.getCorrectionDeclAs<VarDecl>();
3048  } else {
3049  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3050  : diag::err_omp_expected_var_arg)
3051  << Id.getName();
3052  return ExprError();
3053  }
3054  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3055  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3056  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3057  return ExprError();
3058  }
3059  Lookup.suppressDiagnostics();
3060 
3061  // OpenMP [2.9.2, Syntax, C/C++]
3062  // Variables must be file-scope, namespace-scope, or static block-scope.
3063  if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3064  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3065  << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3066  bool IsDecl =
3068  Diag(VD->getLocation(),
3069  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3070  << VD;
3071  return ExprError();
3072  }
3073 
3074  VarDecl *CanonicalVD = VD->getCanonicalDecl();
3075  NamedDecl *ND = CanonicalVD;
3076  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3077  // A threadprivate directive for file-scope variables must appear outside
3078  // any definition or declaration.
3079  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3080  !getCurLexicalContext()->isTranslationUnit()) {
3081  Diag(Id.getLoc(), diag::err_omp_var_scope)
3082  << getOpenMPDirectiveName(Kind) << VD;
3083  bool IsDecl =
3085  Diag(VD->getLocation(),
3086  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3087  << VD;
3088  return ExprError();
3089  }
3090  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3091  // A threadprivate directive for static class member variables must appear
3092  // in the class definition, in the same scope in which the member
3093  // variables are declared.
3094  if (CanonicalVD->isStaticDataMember() &&
3095  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3096  Diag(Id.getLoc(), diag::err_omp_var_scope)
3097  << getOpenMPDirectiveName(Kind) << VD;
3098  bool IsDecl =
3100  Diag(VD->getLocation(),
3101  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3102  << VD;
3103  return ExprError();
3104  }
3105  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3106  // A threadprivate directive for namespace-scope variables must appear
3107  // outside any definition or declaration other than the namespace
3108  // definition itself.
3109  if (CanonicalVD->getDeclContext()->isNamespace() &&
3110  (!getCurLexicalContext()->isFileContext() ||
3111  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3112  Diag(Id.getLoc(), diag::err_omp_var_scope)
3113  << getOpenMPDirectiveName(Kind) << VD;
3114  bool IsDecl =
3116  Diag(VD->getLocation(),
3117  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3118  << VD;
3119  return ExprError();
3120  }
3121  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3122  // A threadprivate directive for static block-scope variables must appear
3123  // in the scope of the variable and not in a nested scope.
3124  if (CanonicalVD->isLocalVarDecl() && CurScope &&
3125  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3126  Diag(Id.getLoc(), diag::err_omp_var_scope)
3127  << getOpenMPDirectiveName(Kind) << VD;
3128  bool IsDecl =
3130  Diag(VD->getLocation(),
3131  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3132  << VD;
3133  return ExprError();
3134  }
3135 
3136  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3137  // A threadprivate directive must lexically precede all references to any
3138  // of the variables in its list.
3139  if (Kind == OMPD_threadprivate && VD->isUsed() &&
3140  !DSAStack->isThreadPrivate(VD)) {
3141  Diag(Id.getLoc(), diag::err_omp_var_used)
3142  << getOpenMPDirectiveName(Kind) << VD;
3143  return ExprError();
3144  }
3145 
3146  QualType ExprType = VD->getType().getNonReferenceType();
3148  SourceLocation(), VD,
3149  /*RefersToEnclosingVariableOrCapture=*/false,
3150  Id.getLoc(), ExprType, VK_LValue);
3151 }
3152 
3155  ArrayRef<Expr *> VarList) {
3156  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3157  CurContext->addDecl(D);
3159  }
3160  return nullptr;
3161 }
3162 
3163 namespace {
3164 class LocalVarRefChecker final
3165  : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3166  Sema &SemaRef;
3167 
3168 public:
3169  bool VisitDeclRefExpr(const DeclRefExpr *E) {
3170  if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3171  if (VD->hasLocalStorage()) {
3172  SemaRef.Diag(E->getBeginLoc(),
3173  diag::err_omp_local_var_in_threadprivate_init)
3174  << E->getSourceRange();
3175  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3176  << VD << VD->getSourceRange();
3177  return true;
3178  }
3179  }
3180  return false;
3181  }
3182  bool VisitStmt(const Stmt *S) {
3183  for (const Stmt *Child : S->children()) {
3184  if (Child && Visit(Child))
3185  return true;
3186  }
3187  return false;
3188  }
3189  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3190 };
3191 } // namespace
3192 
3196  for (Expr *RefExpr : VarList) {
3197  auto *DE = cast<DeclRefExpr>(RefExpr);
3198  auto *VD = cast<VarDecl>(DE->getDecl());
3199  SourceLocation ILoc = DE->getExprLoc();
3200 
3201  // Mark variable as used.
3202  VD->setReferenced();
3203  VD->markUsed(Context);
3204 
3205  QualType QType = VD->getType();
3206  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3207  // It will be analyzed later.
3208  Vars.push_back(DE);
3209  continue;
3210  }
3211 
3212  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3213  // A threadprivate variable must not have an incomplete type.
3214  if (RequireCompleteType(ILoc, VD->getType(),
3215  diag::err_omp_threadprivate_incomplete_type)) {
3216  continue;
3217  }
3218 
3219  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3220  // A threadprivate variable must not have a reference type.
3221  if (VD->getType()->isReferenceType()) {
3222  Diag(ILoc, diag::err_omp_ref_type_arg)
3223  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3224  bool IsDecl =
3226  Diag(VD->getLocation(),
3227  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3228  << VD;
3229  continue;
3230  }
3231 
3232  // Check if this is a TLS variable. If TLS is not being supported, produce
3233  // the corresponding diagnostic.
3234  if ((VD->getTLSKind() != VarDecl::TLS_None &&
3235  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3236  getLangOpts().OpenMPUseTLS &&
3237  getASTContext().getTargetInfo().isTLSSupported())) ||
3238  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3239  !VD->isLocalVarDecl())) {
3240  Diag(ILoc, diag::err_omp_var_thread_local)
3241  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3242  bool IsDecl =
3244  Diag(VD->getLocation(),
3245  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3246  << VD;
3247  continue;
3248  }
3249 
3250  // Check if initial value of threadprivate variable reference variable with
3251  // local storage (it is not supported by runtime).
3252  if (const Expr *Init = VD->getAnyInitializer()) {
3253  LocalVarRefChecker Checker(*this);
3254  if (Checker.Visit(Init))
3255  continue;
3256  }
3257 
3258  Vars.push_back(RefExpr);
3259  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3260  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3261  Context, SourceRange(Loc, Loc)));
3263  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3264  }
3265  OMPThreadPrivateDecl *D = nullptr;
3266  if (!Vars.empty()) {
3268  Vars);
3269  D->setAccess(AS_public);
3270  }
3271  return D;
3272 }
3273 
3274 static OMPAllocateDeclAttr::AllocatorTypeTy
3275 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3276  if (!Allocator)
3277  return OMPAllocateDeclAttr::OMPNullMemAlloc;
3278  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3279  Allocator->isInstantiationDependent() ||
3280  Allocator->containsUnexpandedParameterPack())
3281  return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3282  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3283  llvm::FoldingSetNodeID AEId;
3284  const Expr *AE = Allocator->IgnoreParenImpCasts();
3285  AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3286  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3287  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3288  const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3289  llvm::FoldingSetNodeID DAEId;
3290  DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3291  /*Canonical=*/true);
3292  if (AEId == DAEId) {
3293  AllocatorKindRes = AllocatorKind;
3294  break;
3295  }
3296  }
3297  return AllocatorKindRes;
3298 }
3299 
3301  Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3302  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3303  if (!VD->hasAttr<OMPAllocateDeclAttr>())
3304  return false;
3305  const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3306  Expr *PrevAllocator = A->getAllocator();
3307  OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3308  getAllocatorKind(S, Stack, PrevAllocator);
3309  bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3310  if (AllocatorsMatch &&
3311  AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3312  Allocator && PrevAllocator) {
3313  const Expr *AE = Allocator->IgnoreParenImpCasts();
3314  const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3315  llvm::FoldingSetNodeID AEId, PAEId;
3316  AE->Profile(AEId, S.Context, /*Canonical=*/true);
3317  PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3318  AllocatorsMatch = AEId == PAEId;
3319  }
3320  if (!AllocatorsMatch) {
3321  SmallString<256> AllocatorBuffer;
3322  llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3323  if (Allocator)
3324  Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3325  SmallString<256> PrevAllocatorBuffer;
3326  llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3327  if (PrevAllocator)
3328  PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3329  S.getPrintingPolicy());
3330 
3331  SourceLocation AllocatorLoc =
3332  Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3333  SourceRange AllocatorRange =
3334  Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3335  SourceLocation PrevAllocatorLoc =
3336  PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3337  SourceRange PrevAllocatorRange =
3338  PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3339  S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3340  << (Allocator ? 1 : 0) << AllocatorStream.str()
3341  << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3342  << AllocatorRange;
3343  S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3344  << PrevAllocatorRange;
3345  return true;
3346  }
3347  return false;
3348 }
3349 
3350 static void
3352  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3353  Expr *Allocator, Expr *Alignment, SourceRange SR) {
3354  if (VD->hasAttr<OMPAllocateDeclAttr>())
3355  return;
3356  if (Alignment &&
3357  (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3358  Alignment->isInstantiationDependent() ||
3359  Alignment->containsUnexpandedParameterPack()))
3360  // Apply later when we have a usable value.
3361  return;
3362  if (Allocator &&
3363  (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3364  Allocator->isInstantiationDependent() ||
3365  Allocator->containsUnexpandedParameterPack()))
3366  return;
3367  auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3368  Allocator, Alignment, SR);
3369  VD->addAttr(A);
3371  ML->DeclarationMarkedOpenMPAllocate(VD, A);
3372 }
3373 
3376  ArrayRef<OMPClause *> Clauses,
3377  DeclContext *Owner) {
3378  assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3379  Expr *Alignment = nullptr;
3380  Expr *Allocator = nullptr;
3381  if (Clauses.empty()) {
3382  // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3383  // allocate directives that appear in a target region must specify an
3384  // allocator clause unless a requires directive with the dynamic_allocators
3385  // clause is present in the same compilation unit.
3386  if (LangOpts.OpenMPIsDevice &&
3387  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3388  targetDiag(Loc, diag::err_expected_allocator_clause);
3389  } else {
3390  for (const OMPClause *C : Clauses)
3391  if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3392  Allocator = AC->getAllocator();
3393  else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3394  Alignment = AC->getAlignment();
3395  else
3396  llvm_unreachable("Unexpected clause on allocate directive");
3397  }
3398  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3399  getAllocatorKind(*this, DSAStack, Allocator);
3401  for (Expr *RefExpr : VarList) {
3402  auto *DE = cast<DeclRefExpr>(RefExpr);
3403  auto *VD = cast<VarDecl>(DE->getDecl());
3404 
3405  // Check if this is a TLS variable or global register.
3406  if (VD->getTLSKind() != VarDecl::TLS_None ||
3407  VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3408  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3409  !VD->isLocalVarDecl()))
3410  continue;
3411 
3412  // If the used several times in the allocate directive, the same allocator
3413  // must be used.
3414  if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3415  AllocatorKind, Allocator))
3416  continue;
3417 
3418  // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3419  // If a list item has a static storage type, the allocator expression in the
3420  // allocator clause must be a constant expression that evaluates to one of
3421  // the predefined memory allocator values.
3422  if (Allocator && VD->hasGlobalStorage()) {
3423  if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3424  Diag(Allocator->getExprLoc(),
3425  diag::err_omp_expected_predefined_allocator)
3426  << Allocator->getSourceRange();
3427  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3429  Diag(VD->getLocation(),
3430  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3431  << VD;
3432  continue;
3433  }
3434  }
3435 
3436  Vars.push_back(RefExpr);
3437  applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3438  DE->getSourceRange());
3439  }
3440  if (Vars.empty())
3441  return nullptr;
3442  if (!Owner)
3443  Owner = getCurLexicalContext();
3444  auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3445  D->setAccess(AS_public);
3446  Owner->addDecl(D);
3448 }
3449 
3452  ArrayRef<OMPClause *> ClauseList) {
3453  OMPRequiresDecl *D = nullptr;
3454  if (!CurContext->isFileContext()) {
3455  Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3456  } else {
3457  D = CheckOMPRequiresDecl(Loc, ClauseList);
3458  if (D) {
3459  CurContext->addDecl(D);
3460  DSAStack->addRequiresDecl(D);
3461  }
3462  }
3464 }
3465 
3467  OpenMPDirectiveKind DKind,
3468  ArrayRef<std::string> Assumptions,
3469  bool SkippedClauses) {
3470  if (!SkippedClauses && Assumptions.empty())
3471  Diag(Loc, diag::err_omp_no_clause_for_directive)
3472  << llvm::omp::getAllAssumeClauseOptions()
3473  << llvm::omp::getOpenMPDirectiveName(DKind);
3474 
3475  auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3476  if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3477  OMPAssumeScoped.push_back(AA);
3478  return;
3479  }
3480 
3481  // Global assumes without assumption clauses are ignored.
3482  if (Assumptions.empty())
3483  return;
3484 
3485  assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3486  "Unexpected omp assumption directive!");
3487  OMPAssumeGlobal.push_back(AA);
3488 
3489  // The OMPAssumeGlobal scope above will take care of new declarations but
3490  // we also want to apply the assumption to existing ones, e.g., to
3491  // declarations in included headers. To this end, we traverse all existing
3492  // declaration contexts and annotate function declarations here.
3493  SmallVector<DeclContext *, 8> DeclContexts;
3494  auto *Ctx = CurContext;
3495  while (Ctx->getLexicalParent())
3496  Ctx = Ctx->getLexicalParent();
3497  DeclContexts.push_back(Ctx);
3498  while (!DeclContexts.empty()) {
3499  DeclContext *DC = DeclContexts.pop_back_val();
3500  for (auto *SubDC : DC->decls()) {
3501  if (SubDC->isInvalidDecl())
3502  continue;
3503  if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3504  DeclContexts.push_back(CTD->getTemplatedDecl());
3505  llvm::append_range(DeclContexts, CTD->specializations());
3506  continue;
3507  }
3508  if (auto *DC = dyn_cast<DeclContext>(SubDC))
3509  DeclContexts.push_back(DC);
3510  if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3511  F->addAttr(AA);
3512  continue;
3513  }
3514  }
3515  }
3516 }
3517 
3519  assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3520  OMPAssumeScoped.pop_back();
3521 }
3522 
3524  ArrayRef<OMPClause *> ClauseList) {
3525  /// For target specific clauses, the requires directive cannot be
3526  /// specified after the handling of any of the target regions in the
3527  /// current compilation unit.
3528  ArrayRef<SourceLocation> TargetLocations =
3529  DSAStack->getEncounteredTargetLocs();
3530  SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3531  if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3532  for (const OMPClause *CNew : ClauseList) {
3533  // Check if any of the requires clauses affect target regions.
3534  if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3535  isa<OMPUnifiedAddressClause>(CNew) ||
3536  isa<OMPReverseOffloadClause>(CNew) ||
3537  isa<OMPDynamicAllocatorsClause>(CNew)) {
3538  Diag(Loc, diag::err_omp_directive_before_requires)
3539  << "target" << getOpenMPClauseName(CNew->getClauseKind());
3540  for (SourceLocation TargetLoc : TargetLocations) {
3541  Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3542  << "target";
3543  }
3544  } else if (!AtomicLoc.isInvalid() &&
3545  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3546  Diag(Loc, diag::err_omp_directive_before_requires)
3547  << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3548  Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3549  << "atomic";
3550  }
3551  }
3552  }
3553 
3554  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3556  ClauseList);
3557  return nullptr;
3558 }
3559 
3560 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3561  const ValueDecl *D,
3562  const DSAStackTy::DSAVarData &DVar,
3563  bool IsLoopIterVar) {
3564  if (DVar.RefExpr) {
3565  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3566  << getOpenMPClauseName(DVar.CKind);
3567  return;
3568  }
3569  enum {
3570  PDSA_StaticMemberShared,
3571  PDSA_StaticLocalVarShared,
3572  PDSA_LoopIterVarPrivate,
3573  PDSA_LoopIterVarLinear,
3574  PDSA_LoopIterVarLastprivate,
3575  PDSA_ConstVarShared,
3576  PDSA_GlobalVarShared,
3577  PDSA_TaskVarFirstprivate,
3578  PDSA_LocalVarPrivate,
3579  PDSA_Implicit
3580  } Reason = PDSA_Implicit;
3581  bool ReportHint = false;
3582  auto ReportLoc = D->getLocation();
3583  auto *VD = dyn_cast<VarDecl>(D);
3584  if (IsLoopIterVar) {
3585  if (DVar.CKind == OMPC_private)
3586  Reason = PDSA_LoopIterVarPrivate;
3587  else if (DVar.CKind == OMPC_lastprivate)
3588  Reason = PDSA_LoopIterVarLastprivate;
3589  else
3590  Reason = PDSA_LoopIterVarLinear;
3591  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3592  DVar.CKind == OMPC_firstprivate) {
3593  Reason = PDSA_TaskVarFirstprivate;
3594  ReportLoc = DVar.ImplicitDSALoc;
3595  } else if (VD && VD->isStaticLocal())
3596  Reason = PDSA_StaticLocalVarShared;
3597  else if (VD && VD->isStaticDataMember())
3598  Reason = PDSA_StaticMemberShared;
3599  else if (VD && VD->isFileVarDecl())
3600  Reason = PDSA_GlobalVarShared;
3601  else if (D->getType().isConstant(SemaRef.getASTContext()))
3602  Reason = PDSA_ConstVarShared;
3603  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3604  ReportHint = true;
3605  Reason = PDSA_LocalVarPrivate;
3606  }
3607  if (Reason != PDSA_Implicit) {
3608  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3609  << Reason << ReportHint
3610  << getOpenMPDirectiveName(Stack->getCurrentDirective());
3611  } else if (DVar.ImplicitDSALoc.isValid()) {
3612  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3613  << getOpenMPClauseName(DVar.CKind);
3614  }
3615 }
3616 
3617 static OpenMPMapClauseKind
3619  bool IsAggregateOrDeclareTarget) {
3621  switch (M) {
3622  case OMPC_DEFAULTMAP_MODIFIER_alloc:
3623  Kind = OMPC_MAP_alloc;
3624  break;
3625  case OMPC_DEFAULTMAP_MODIFIER_to:
3626  Kind = OMPC_MAP_to;
3627  break;
3628  case OMPC_DEFAULTMAP_MODIFIER_from:
3629  Kind = OMPC_MAP_from;
3630  break;
3631  case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3632  Kind = OMPC_MAP_tofrom;
3633  break;
3634  case OMPC_DEFAULTMAP_MODIFIER_present:
3635  // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3636  // If implicit-behavior is present, each variable referenced in the
3637  // construct in the category specified by variable-category is treated as if
3638  // it had been listed in a map clause with the map-type of alloc and
3639  // map-type-modifier of present.
3640  Kind = OMPC_MAP_alloc;
3641  break;
3642  case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3644  llvm_unreachable("Unexpected defaultmap implicit behavior");
3645  case OMPC_DEFAULTMAP_MODIFIER_none:
3646  case OMPC_DEFAULTMAP_MODIFIER_default:
3648  // IsAggregateOrDeclareTarget could be true if:
3649  // 1. the implicit behavior for aggregate is tofrom
3650  // 2. it's a declare target link
3651  if (IsAggregateOrDeclareTarget) {
3652  Kind = OMPC_MAP_tofrom;
3653  break;
3654  }
3655  llvm_unreachable("Unexpected defaultmap implicit behavior");
3656  }
3657  assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3658  return Kind;
3659 }
3660 
3661 namespace {
3662 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3663  DSAStackTy *Stack;
3664  Sema &SemaRef;
3665  bool ErrorFound = false;
3666  bool TryCaptureCXXThisMembers = false;
3667  CapturedStmt *CS = nullptr;
3668  const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3669  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3670  llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3671  llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3673  ImplicitMapModifier[DefaultmapKindNum];
3674  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3675  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3676 
3677  void VisitSubCaptures(OMPExecutableDirective *S) {
3678  // Check implicitly captured variables.
3679  if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3680  return;
3681  if (S->getDirectiveKind() == OMPD_atomic ||
3682  S->getDirectiveKind() == OMPD_critical ||
3683  S->getDirectiveKind() == OMPD_section ||
3684  S->getDirectiveKind() == OMPD_master ||
3685  S->getDirectiveKind() == OMPD_masked ||
3686  isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3687  Visit(S->getAssociatedStmt());
3688  return;
3689  }
3690  visitSubCaptures(S->getInnermostCapturedStmt());
3691  // Try to capture inner this->member references to generate correct mappings
3692  // and diagnostics.
3693  if (TryCaptureCXXThisMembers ||
3694  (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3695  llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3696  [](const CapturedStmt::Capture &C) {
3697  return C.capturesThis();
3698  }))) {
3699  bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3700  TryCaptureCXXThisMembers = true;
3701  Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3702  TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3703  }
3704  // In tasks firstprivates are not captured anymore, need to analyze them
3705  // explicitly.
3706  if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3707  !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3708  for (OMPClause *C : S->clauses())
3709  if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3710  for (Expr *Ref : FC->varlists())
3711  Visit(Ref);
3712  }
3713  }
3714  }
3715 
3716 public:
3717  void VisitDeclRefExpr(DeclRefExpr *E) {
3718  if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3721  return;
3722  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3723  // Check the datasharing rules for the expressions in the clauses.
3724  if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3725  !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3726  !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3727  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3728  if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3729  Visit(CED->getInit());
3730  return;
3731  }
3732  } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3733  // Do not analyze internal variables and do not enclose them into
3734  // implicit clauses.
3735  if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3736  return;
3737  VD = VD->getCanonicalDecl();
3738  // Skip internally declared variables.
3739  if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3740  !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3741  !Stack->isImplicitTaskFirstprivate(VD))
3742  return;
3743  // Skip allocators in uses_allocators clauses.
3744  if (Stack->isUsesAllocatorsDecl(VD))
3745  return;
3746 
3747  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3748  // Check if the variable has explicit DSA set and stop analysis if it so.
3749  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3750  return;
3751 
3752  // Skip internally declared static variables.
3753  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3754  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3755  if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3756  (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3757  !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3758  !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3759  !Stack->isImplicitTaskFirstprivate(VD))
3760  return;
3761 
3762  SourceLocation ELoc = E->getExprLoc();
3763  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3764  // The default(none) clause requires that each variable that is referenced
3765  // in the construct, and does not have a predetermined data-sharing
3766  // attribute, must have its data-sharing attribute explicitly determined
3767  // by being listed in a data-sharing attribute clause.
3768  if (DVar.CKind == OMPC_unknown &&
3769  (Stack->getDefaultDSA() == DSA_none ||
3770  Stack->getDefaultDSA() == DSA_private ||
3771  Stack->getDefaultDSA() == DSA_firstprivate) &&
3772  isImplicitOrExplicitTaskingRegion(DKind) &&
3773  VarsWithInheritedDSA.count(VD) == 0) {
3774  bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3775  if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3776  Stack->getDefaultDSA() == DSA_private)) {
3777  DSAStackTy::DSAVarData DVar =
3778  Stack->getImplicitDSA(VD, /*FromParent=*/false);
3779  InheritedDSA = DVar.CKind == OMPC_unknown;
3780  }
3781  if (InheritedDSA)
3782  VarsWithInheritedDSA[VD] = E;
3783  if (Stack->getDefaultDSA() == DSA_none)
3784  return;
3785  }
3786 
3787  // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3788  // If implicit-behavior is none, each variable referenced in the
3789  // construct that does not have a predetermined data-sharing attribute
3790  // and does not appear in a to or link clause on a declare target
3791  // directive must be listed in a data-mapping attribute clause, a
3792  // data-sharing attribute clause (including a data-sharing attribute
3793  // clause on a combined construct where target. is one of the
3794  // constituent constructs), or an is_device_ptr clause.
3795  OpenMPDefaultmapClauseKind ClauseKind =
3797  if (SemaRef.getLangOpts().OpenMP >= 50) {
3798  bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3799  OMPC_DEFAULTMAP_MODIFIER_none;
3800  if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3801  VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3802  // Only check for data-mapping attribute and is_device_ptr here
3803  // since we have already make sure that the declaration does not
3804  // have a data-sharing attribute above
3805  if (!Stack->checkMappableExprComponentListsForDecl(
3806  VD, /*CurrentRegionOnly=*/true,
3808  MapExprComponents,
3809  OpenMPClauseKind) {
3810  auto MI = MapExprComponents.rbegin();
3811  auto ME = MapExprComponents.rend();
3812  return MI != ME && MI->getAssociatedDeclaration() == VD;
3813  })) {
3814  VarsWithInheritedDSA[VD] = E;
3815  return;
3816  }
3817  }
3818  }
3819  if (SemaRef.getLangOpts().OpenMP > 50) {
3820  bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3821  OMPC_DEFAULTMAP_MODIFIER_present;
3822  if (IsModifierPresent) {
3823  if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3824  OMPC_MAP_MODIFIER_present)) {
3825  ImplicitMapModifier[ClauseKind].push_back(
3826  OMPC_MAP_MODIFIER_present);
3827  }
3828  }
3829  }
3830 
3831  if (isOpenMPTargetExecutionDirective(DKind) &&
3832  !Stack->isLoopControlVariable(VD).first) {
3833  if (!Stack->checkMappableExprComponentListsForDecl(
3834  VD, /*CurrentRegionOnly=*/true,
3836  StackComponents,
3837  OpenMPClauseKind) {
3838  if (SemaRef.LangOpts.OpenMP >= 50)
3839  return !StackComponents.empty();
3840  // Variable is used if it has been marked as an array, array
3841  // section, array shaping or the variable iself.
3842  return StackComponents.size() == 1 ||
3843  llvm::all_of(
3844  llvm::drop_begin(llvm::reverse(StackComponents)),
3845  [](const OMPClauseMappableExprCommon::
3846  MappableComponent &MC) {
3847  return MC.getAssociatedDeclaration() ==
3848  nullptr &&
3849  (isa<OMPArraySectionExpr>(
3850  MC.getAssociatedExpression()) ||
3851  isa<OMPArrayShapingExpr>(
3852  MC.getAssociatedExpression()) ||
3853  isa<ArraySubscriptExpr>(
3854  MC.getAssociatedExpression()));
3855  });
3856  })) {
3857  bool IsFirstprivate = false;
3858  // By default lambdas are captured as firstprivates.
3859  if (const auto *RD =
3861  IsFirstprivate = RD->isLambda();
3862  IsFirstprivate =
3863  IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3864  if (IsFirstprivate) {
3865  ImplicitFirstprivate.emplace_back(E);
3866  } else {
3868  Stack->getDefaultmapModifier(ClauseKind);
3870  M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3871  ImplicitMap[ClauseKind][Kind].emplace_back(E);
3872  }
3873  return;
3874  }
3875  }
3876 
3877  // OpenMP [2.9.3.6, Restrictions, p.2]
3878  // A list item that appears in a reduction clause of the innermost
3879  // enclosing worksharing or parallel construct may not be accessed in an
3880  // explicit task.
3881  DVar = Stack->hasInnermostDSA(
3882  VD,
3883  [](OpenMPClauseKind C, bool AppliedToPointee) {
3884  return C == OMPC_reduction && !AppliedToPointee;
3885  },
3886  [](OpenMPDirectiveKind K) {
3887  return isOpenMPParallelDirective(K) ||
3889  },
3890  /*FromParent=*/true);
3891  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3892  ErrorFound = true;
3893  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3894  reportOriginalDsa(SemaRef, Stack, VD, DVar);
3895  return;
3896  }
3897 
3898  // Define implicit data-sharing attributes for task.
3899  DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3900  if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3901  (((Stack->getDefaultDSA() == DSA_firstprivate &&
3902  DVar.CKind == OMPC_firstprivate) ||
3903  (Stack->getDefaultDSA() == DSA_private &&
3904  DVar.CKind == OMPC_private)) &&
3905  !DVar.RefExpr)) &&
3906  !Stack->isLoopControlVariable(VD).first) {
3907  if (Stack->getDefaultDSA() == DSA_private)
3908  ImplicitPrivate.push_back(E);
3909  else
3910  ImplicitFirstprivate.push_back(E);
3911  return;
3912  }
3913 
3914  // Store implicitly used globals with declare target link for parent
3915  // target.
3916  if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3917  *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3918  Stack->addToParentTargetRegionLinkGlobals(E);
3919  return;
3920  }
3921  }
3922  }
3923  void VisitMemberExpr(MemberExpr *E) {
3924  if (E->isTypeDependent() || E->isValueDependent() ||
3926  return;
3927  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3928  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3929  if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3930  if (!FD)
3931  return;
3932  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3933  // Check if the variable has explicit DSA set and stop analysis if it
3934  // so.
3935  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3936  return;
3937 
3938  if (isOpenMPTargetExecutionDirective(DKind) &&
3939  !Stack->isLoopControlVariable(FD).first &&
3940  !Stack->checkMappableExprComponentListsForDecl(
3941  FD, /*CurrentRegionOnly=*/true,
3943  StackComponents,
3944  OpenMPClauseKind) {
3945  return isa<CXXThisExpr>(
3946  cast<MemberExpr>(
3947  StackComponents.back().getAssociatedExpression())
3948  ->getBase()
3949  ->IgnoreParens());
3950  })) {
3951  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3952  // A bit-field cannot appear in a map clause.
3953  //
3954  if (FD->isBitField())
3955  return;
3956 
3957  // Check to see if the member expression is referencing a class that
3958  // has already been explicitly mapped
3959  if (Stack->isClassPreviouslyMapped(TE->getType()))
3960  return;
3961 
3963  Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3964  OpenMPDefaultmapClauseKind ClauseKind =
3967  Modifier, /*IsAggregateOrDeclareTarget*/ true);
3968  ImplicitMap[ClauseKind][Kind].emplace_back(E);
3969  return;
3970  }
3971 
3972  SourceLocation ELoc = E->getExprLoc();
3973  // OpenMP [2.9.3.6, Restrictions, p.2]
3974  // A list item that appears in a reduction clause of the innermost
3975  // enclosing worksharing or parallel construct may not be accessed in
3976  // an explicit task.
3977  DVar = Stack->hasInnermostDSA(
3978  FD,
3979  [](OpenMPClauseKind C, bool AppliedToPointee) {
3980  return C == OMPC_reduction && !AppliedToPointee;
3981  },
3982  [](OpenMPDirectiveKind K) {
3983  return isOpenMPParallelDirective(K) ||
3985  },
3986  /*FromParent=*/true);
3987  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3988  ErrorFound = true;
3989  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3990  reportOriginalDsa(SemaRef, Stack, FD, DVar);
3991  return;
3992  }
3993 
3994  // Define implicit data-sharing attributes for task.
3995  DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3996  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3997  !Stack->isLoopControlVariable(FD).first) {
3998  // Check if there is a captured expression for the current field in the
3999  // region. Do not mark it as firstprivate unless there is no captured
4000  // expression.
4001  // TODO: try to make it firstprivate.
4002  if (DVar.CKind != OMPC_unknown)
4003  ImplicitFirstprivate.push_back(E);
4004  }
4005  return;
4006  }
4007  if (isOpenMPTargetExecutionDirective(DKind)) {
4009  if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4010  Stack->getCurrentDirective(),
4011  /*NoDiagnose=*/true))
4012  return;
4013  const auto *VD = cast<ValueDecl>(
4014  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4015  if (!Stack->checkMappableExprComponentListsForDecl(
4016  VD, /*CurrentRegionOnly=*/true,
4017  [&CurComponents](
4019  StackComponents,
4020  OpenMPClauseKind) {
4021  auto CCI = CurComponents.rbegin();
4022  auto CCE = CurComponents.rend();
4023  for (const auto &SC : llvm::reverse(StackComponents)) {
4024  // Do both expressions have the same kind?
4025  if (CCI->getAssociatedExpression()->getStmtClass() !=
4026  SC.getAssociatedExpression()->getStmtClass())
4027  if (!((isa<OMPArraySectionExpr>(
4028  SC.getAssociatedExpression()) ||
4029  isa<OMPArrayShapingExpr>(
4030  SC.getAssociatedExpression())) &&
4031  isa<ArraySubscriptExpr>(
4032  CCI->getAssociatedExpression())))
4033  return false;
4034 
4035  const Decl *CCD = CCI->getAssociatedDeclaration();
4036  const Decl *SCD = SC.getAssociatedDeclaration();
4037  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4038  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4039  if (SCD != CCD)
4040  return false;
4041  std::advance(CCI, 1);
4042  if (CCI == CCE)
4043  break;
4044  }
4045  return true;
4046  })) {
4047  Visit(E->getBase());
4048  }
4049  } else if (!TryCaptureCXXThisMembers) {
4050  Visit(E->getBase());
4051  }
4052  }
4053  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4054  for (OMPClause *C : S->clauses()) {
4055  // Skip analysis of arguments of private clauses for task|target
4056  // directives.
4057  if (isa_and_nonnull<OMPPrivateClause>(C))
4058  continue;
4059  // Skip analysis of arguments of implicitly defined firstprivate clause
4060  // for task|target directives.
4061  // Skip analysis of arguments of implicitly defined map clause for target
4062  // directives.
4063  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4064  C->isImplicit() &&
4065  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4066  for (Stmt *CC : C->children()) {
4067  if (CC)
4068  Visit(CC);
4069  }
4070  }
4071  }
4072  // Check implicitly captured variables.
4073  VisitSubCaptures(S);
4074  }
4075 
4076  void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4077  // Loop transformation directives do not introduce data sharing
4078  VisitStmt(S);
4079  }
4080 
4081  void VisitCallExpr(CallExpr *S) {
4082  for (Stmt *C : S->arguments()) {
4083  if (C) {
4084  // Check implicitly captured variables in the task-based directives to
4085  // check if they must be firstprivatized.
4086  Visit(C);
4087  }
4088  }
4089  if (Expr *Callee = S->getCallee()) {
4090  auto *CI = Callee->IgnoreParenImpCasts();
4091  if (auto *CE = dyn_cast<MemberExpr>(CI))
4092  Visit(CE->getBase());
4093  else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4094  Visit(CE);
4095  }
4096  }
4097  void VisitStmt(Stmt *S) {
4098  for (Stmt *C : S->children()) {
4099  if (C) {
4100  // Check implicitly captured variables in the task-based directives to
4101  // check if they must be firstprivatized.
4102  Visit(C);
4103  }
4104  }
4105  }
4106 
4107  void visitSubCaptures(CapturedStmt *S) {
4108  for (const CapturedStmt::Capture &Cap : S->captures()) {
4109  if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4110  continue;
4111  VarDecl *VD = Cap.getCapturedVar();
4112  // Do not try to map the variable if it or its sub-component was mapped
4113  // already.
4114  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4115  Stack->checkMappableExprComponentListsForDecl(
4116  VD, /*CurrentRegionOnly=*/true,
4118  OpenMPClauseKind) { return true; }))
4119  continue;
4121  SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4122  Cap.getLocation(), /*RefersToCapture=*/true);
4123  Visit(DRE);
4124  }
4125  }
4126  bool isErrorFound() const { return ErrorFound; }
4127  ArrayRef<Expr *> getImplicitFirstprivate() const {
4128  return ImplicitFirstprivate;
4129  }
4130  ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4131  ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4132  OpenMPMapClauseKind MK) const {
4133  return ImplicitMap[DK][MK];
4134  }
4136  getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4137  return ImplicitMapModifier[Kind];
4138  }
4139  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4140  return VarsWithInheritedDSA;
4141  }
4142 
4143  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4144  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4145  // Process declare target link variables for the target directives.
4146  if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4147  for (DeclRefExpr *E : Stack->getLinkGlobals())
4148  Visit(E);
4149  }
4150  }
4151 };
4152 } // namespace
4153 
4154 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4155  OpenMPDirectiveKind DKind,
4156  bool ScopeEntry) {
4159  Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4160  if (isOpenMPTeamsDirective(DKind))
4161  Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4162  if (isOpenMPParallelDirective(DKind))
4163  Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4164  if (isOpenMPWorksharingDirective(DKind))
4165  Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4166  if (isOpenMPSimdDirective(DKind))
4167  Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4168  Stack->handleConstructTrait(Traits, ScopeEntry);
4169 }
4170 
4172  switch (DKind) {
4173  case OMPD_parallel:
4174  case OMPD_parallel_for:
4175  case OMPD_parallel_for_simd:
4176  case OMPD_parallel_sections:
4177  case OMPD_parallel_master:
4178  case OMPD_parallel_masked:
4179  case OMPD_parallel_loop:
4180  case OMPD_teams:
4181  case OMPD_teams_distribute:
4182  case OMPD_teams_distribute_simd: {
4183  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4184  QualType KmpInt32PtrTy =
4185  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4186  Sema::CapturedParamNameType Params[] = {
4187  std::make_pair(".global_tid.", KmpInt32PtrTy),
4188  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4189  std::make_pair(StringRef(), QualType()) // __context with shared vars
4190  };
4191  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4192  Params);
4193  break;
4194  }
4195  case OMPD_target_teams:
4196  case OMPD_target_parallel:
4197  case OMPD_target_parallel_for:
4198  case OMPD_target_parallel_for_simd:
4199  case OMPD_target_teams_loop:
4200  case OMPD_target_parallel_loop:
4201  case OMPD_target_teams_distribute:
4202  case OMPD_target_teams_distribute_simd: {
4203  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4205  QualType KmpInt32PtrTy =
4206  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4207  QualType Args[] = {VoidPtrTy};
4209  EPI.Variadic = true;
4210  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4211  Sema::CapturedParamNameType Params[] = {
4212  std::make_pair(".global_tid.", KmpInt32Ty),
4213  std::make_pair(".part_id.", KmpInt32PtrTy),
4214  std::make_pair(".privates.", VoidPtrTy),
4215  std::make_pair(
4216  ".copy_fn.",
4217  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4218  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4219  std::make_pair(StringRef(), QualType()) // __context with shared vars
4220  };
4221  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4222  Params, /*OpenMPCaptureLevel=*/0);
4223  // Mark this captured region as inlined, because we don't use outlined
4224  // function directly.
4226  AlwaysInlineAttr::CreateImplicit(
4228  AlwaysInlineAttr::Keyword_forceinline));
4229  Sema::CapturedParamNameType ParamsTarget[] = {
4230  std::make_pair(StringRef(), QualType()) // __context with shared vars
4231  };
4232  // Start a captured region for 'target' with no implicit parameters.
4233  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4234  ParamsTarget, /*OpenMPCaptureLevel=*/1);
4235  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4236  std::make_pair(".global_tid.", KmpInt32PtrTy),
4237  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4238  std::make_pair(StringRef(), QualType()) // __context with shared vars
4239  };
4240  // Start a captured region for 'teams' or 'parallel'. Both regions have
4241  // the same implicit parameters.
4242  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4243  ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4244  break;
4245  }
4246  case OMPD_target:
4247  case OMPD_target_simd: {
4248  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4250  QualType KmpInt32PtrTy =
4251  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4252  QualType Args[] = {VoidPtrTy};
4254  EPI.Variadic = true;
4255  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4256  Sema::CapturedParamNameType Params[] = {
4257  std::make_pair(".global_tid.", KmpInt32Ty),
4258  std::make_pair(".part_id.", KmpInt32PtrTy),
4259  std::make_pair(".privates.", VoidPtrTy),
4260  std::make_pair(
4261  ".copy_fn.",
4262  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4263  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4264  std::make_pair(StringRef(), QualType()) // __context with shared vars
4265  };
4266  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4267  Params, /*OpenMPCaptureLevel=*/0);
4268  // Mark this captured region as inlined, because we don't use outlined
4269  // function directly.
4271  AlwaysInlineAttr::CreateImplicit(
4273  AlwaysInlineAttr::Keyword_forceinline));
4274  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4275  std::make_pair(StringRef(), QualType()),
4276  /*OpenMPCaptureLevel=*/1);
4277  break;
4278  }
4279  case OMPD_atomic:
4280  case OMPD_critical:
4281  case OMPD_section:
4282  case OMPD_master:
4283  case OMPD_masked:
4284  case OMPD_tile:
4285  case OMPD_unroll:
4286  break;
4287  case OMPD_loop:
4288  // TODO: 'loop' may require additional parameters depending on the binding.
4289  // Treat similar to OMPD_simd/OMPD_for for now.
4290  case OMPD_simd:
4291  case OMPD_for:
4292  case OMPD_for_simd:
4293  case OMPD_sections:
4294  case OMPD_single:
4295  case OMPD_taskgroup:
4296  case OMPD_distribute:
4297  case OMPD_distribute_simd:
4298  case OMPD_ordered:
4299  case OMPD_target_data:
4300  case OMPD_dispatch: {
4301  Sema::CapturedParamNameType Params[] = {
4302  std::make_pair(StringRef(), QualType()) // __context with shared vars
4303  };
4304  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305  Params);
4306  break;
4307  }
4308  case OMPD_task: {
4309  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4311  QualType KmpInt32PtrTy =
4312  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4313  QualType Args[] = {VoidPtrTy};
4315  EPI.Variadic = true;
4316  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4317  Sema::CapturedParamNameType Params[] = {
4318  std::make_pair(".global_tid.", KmpInt32Ty),
4319  std::make_pair(".part_id.", KmpInt32PtrTy),
4320  std::make_pair(".privates.", VoidPtrTy),
4321  std::make_pair(
4322  ".copy_fn.",
4323  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4324  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4325  std::make_pair(StringRef(), QualType()) // __context with shared vars
4326  };
4327  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4328  Params);
4329  // Mark this captured region as inlined, because we don't use outlined
4330  // function directly.
4332  AlwaysInlineAttr::CreateImplicit(
4334  AlwaysInlineAttr::Keyword_forceinline));
4335  break;
4336  }
4337  case OMPD_taskloop:
4338  case OMPD_taskloop_simd:
4339  case OMPD_master_taskloop:
4340  case OMPD_masked_taskloop:
4341  case OMPD_masked_taskloop_simd:
4342  case OMPD_master_taskloop_simd: {
4343  QualType KmpInt32Ty =
4344  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4345  .withConst();
4346  QualType KmpUInt64Ty =
4347  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4348  .withConst();
4349  QualType KmpInt64Ty =
4350  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4351  .withConst();
4353  QualType KmpInt32PtrTy =
4354  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4355  QualType Args[] = {VoidPtrTy};
4357  EPI.Variadic = true;
4358  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4359  Sema::CapturedParamNameType Params[] = {
4360  std::make_pair(".global_tid.", KmpInt32Ty),
4361  std::make_pair(".part_id.", KmpInt32PtrTy),
4362  std::make_pair(".privates.", VoidPtrTy),
4363  std::make_pair(
4364  ".copy_fn.",
4365  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4366  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4367  std::make_pair(".lb.", KmpUInt64Ty),
4368  std::make_pair(".ub.", KmpUInt64Ty),
4369  std::make_pair(".st.", KmpInt64Ty),
4370  std::make_pair(".liter.", KmpInt32Ty),
4371  std::make_pair(".reductions.", VoidPtrTy),
4372  std::make_pair(StringRef(), QualType()) // __context with shared vars
4373  };
4374  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4375  Params);
4376  // Mark this captured region as inlined, because we don't use outlined
4377  // function directly.
4379  AlwaysInlineAttr::CreateImplicit(
4381  AlwaysInlineAttr::Keyword_forceinline));
4382  break;
4383  }
4384  case OMPD_parallel_masked_taskloop:
4385  case OMPD_parallel_masked_taskloop_simd:
4386  case OMPD_parallel_master_taskloop:
4387  case OMPD_parallel_master_taskloop_simd: {
4388  QualType KmpInt32Ty =
4389  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4390  .withConst();
4391  QualType KmpUInt64Ty =
4392  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4393  .withConst();
4394  QualType KmpInt64Ty =
4395  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4396  .withConst();
4398  QualType KmpInt32PtrTy =
4399  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4400  Sema::CapturedParamNameType ParamsParallel[] = {
4401  std::make_pair(".global_tid.", KmpInt32PtrTy),
4402  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4403  std::make_pair(StringRef(), QualType()) // __context with shared vars
4404  };
4405  // Start a captured region for 'parallel'.
4406  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4407  ParamsParallel, /*OpenMPCaptureLevel=*/0);
4408  QualType Args[] = {VoidPtrTy};
4410  EPI.Variadic = true;
4411  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4412  Sema::CapturedParamNameType Params[] = {
4413  std::make_pair(".global_tid.", KmpInt32Ty),
4414  std::make_pair(".part_id.", KmpInt32PtrTy),
4415  std::make_pair(".privates.", VoidPtrTy),
4416  std::make_pair(
4417  ".copy_fn.",
4418  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4419  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4420  std::make_pair(".lb.", KmpUInt64Ty),
4421  std::make_pair(".ub.", KmpUInt64Ty),
4422  std::make_pair(".st.", KmpInt64Ty),
4423  std::make_pair(".liter.", KmpInt32Ty),
4424  std::make_pair(".reductions.", VoidPtrTy),
4425  std::make_pair(StringRef(), QualType()) // __context with shared vars
4426  };
4427  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4428  Params, /*OpenMPCaptureLevel=*/1);
4429  // Mark this captured region as inlined, because we don't use outlined
4430  // function directly.
4432  AlwaysInlineAttr::CreateImplicit(
4434  AlwaysInlineAttr::Keyword_forceinline));
4435  break;
4436  }
4437  case OMPD_distribute_parallel_for_simd:
4438  case OMPD_distribute_parallel_for: {
4439  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4440  QualType KmpInt32PtrTy =
4441  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4442  Sema::CapturedParamNameType Params[] = {
4443  std::make_pair(".global_tid.", KmpInt32PtrTy),
4444  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4445  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4446  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4447  std::make_pair(StringRef(), QualType()) // __context with shared vars
4448  };
4449  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4450  Params);
4451  break;
4452  }
4453  case OMPD_target_teams_distribute_parallel_for:
4454  case OMPD_target_teams_distribute_parallel_for_simd: {
4455  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4456  QualType KmpInt32PtrTy =
4457  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4459 
4460  QualType Args[] = {VoidPtrTy};
4462  EPI.Variadic = true;
4463  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4464  Sema::CapturedParamNameType Params[] = {
4465  std::make_pair(".global_tid.", KmpInt32Ty),
4466  std::make_pair(".part_id.", KmpInt32PtrTy),
4467  std::make_pair(".privates.", VoidPtrTy),
4468  std::make_pair(
4469  ".copy_fn.",
4470  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4471  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4472  std::make_pair(StringRef(), QualType()) // __context with shared vars
4473  };
4474  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4475  Params, /*OpenMPCaptureLevel=*/0);
4476  // Mark this captured region as inlined, because we don't use outlined
4477  // function directly.
4479  AlwaysInlineAttr::CreateImplicit(
4481  AlwaysInlineAttr::Keyword_forceinline));
4482  Sema::CapturedParamNameType ParamsTarget[] = {
4483  std::make_pair(StringRef(), QualType()) // __context with shared vars
4484  };
4485  // Start a captured region for 'target' with no implicit parameters.
4486  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4487  ParamsTarget, /*OpenMPCaptureLevel=*/1);
4488 
4489  Sema::CapturedParamNameType ParamsTeams[] = {
4490  std::make_pair(".global_tid.", KmpInt32PtrTy),
4491  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4492  std::make_pair(StringRef(), QualType()) // __context with shared vars
4493  };
4494  // Start a captured region for 'target' with no implicit parameters.
4495  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4496  ParamsTeams, /*OpenMPCaptureLevel=*/2);
4497 
4498  Sema::CapturedParamNameType ParamsParallel[] = {
4499  std::make_pair(".global_tid.", KmpInt32PtrTy),
4500  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4501  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4502  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4503  std::make_pair(StringRef(), QualType()) // __context with shared vars
4504  };
4505  // Start a captured region for 'teams' or 'parallel'. Both regions have
4506  // the same implicit parameters.
4507  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4508  ParamsParallel, /*OpenMPCaptureLevel=*/3);
4509  break;
4510  }
4511 
4512  case OMPD_teams_loop: {
4513  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4514  QualType KmpInt32PtrTy =
4515  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4516 
4517  Sema::CapturedParamNameType ParamsTeams[] = {
4518  std::make_pair(".global_tid.", KmpInt32PtrTy),
4519  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4520  std::make_pair(StringRef(), QualType()) // __context with shared vars
4521  };
4522  // Start a captured region for 'teams'.
4523  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4524  ParamsTeams, /*OpenMPCaptureLevel=*/0);
4525  break;
4526  }
4527 
4528  case OMPD_teams_distribute_parallel_for:
4529  case OMPD_teams_distribute_parallel_for_simd: {
4530  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4531  QualType KmpInt32PtrTy =
4532  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4533 
4534  Sema::CapturedParamNameType ParamsTeams[] = {
4535  std::make_pair(".global_tid.", KmpInt32PtrTy),
4536  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4537  std::make_pair(StringRef(), QualType()) // __context with shared vars
4538  };
4539  // Start a captured region for 'target' with no implicit parameters.
4540  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4541  ParamsTeams, /*OpenMPCaptureLevel=*/0);
4542 
4543  Sema::CapturedParamNameType ParamsParallel[] = {
4544  std::make_pair(".global_tid.", KmpInt32PtrTy),
4545  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4546  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4547  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4548  std::make_pair(StringRef(), QualType()) // __context with shared vars
4549  };
4550  // Start a captured region for 'teams' or 'parallel'. Both regions have
4551  // the same implicit parameters.
4552  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4553  ParamsParallel, /*OpenMPCaptureLevel=*/1);
4554  break;
4555  }
4556  case OMPD_target_update:
4557  case OMPD_target_enter_data:
4558  case OMPD_target_exit_data: {
4559  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4561  QualType KmpInt32PtrTy =
4562  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4563  QualType Args[] = {VoidPtrTy};
4565  EPI.Variadic = true;
4566  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4567  Sema::CapturedParamNameType Params[] = {
4568  std::make_pair(".global_tid.", KmpInt32Ty),
4569  std::make_pair(".part_id.", KmpInt32PtrTy),
4570  std::make_pair(".privates.", VoidPtrTy),
4571  std::make_pair(
4572  ".copy_fn.",
4573  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4574  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4575  std::make_pair(StringRef(), QualType()) // __context with shared vars
4576  };
4577  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4578  Params);
4579  // Mark this captured region as inlined, because we don't use outlined
4580  // function directly.
4582  AlwaysInlineAttr::CreateImplicit(
4584  AlwaysInlineAttr::Keyword_forceinline));
4585  break;
4586  }
4587  case OMPD_threadprivate:
4588  case OMPD_allocate:
4589  case OMPD_taskyield:
4590  case OMPD_error:
4591  case OMPD_barrier:
4592  case OMPD_taskwait:
4593  case OMPD_cancellation_point:
4594  case OMPD_cancel:
4595  case OMPD_flush:
4596  case OMPD_depobj:
4597  case OMPD_scan:
4598  case OMPD_declare_reduction:
4599  case OMPD_declare_mapper:
4600  case OMPD_declare_simd:
4601  case OMPD_declare_target:
4602  case OMPD_end_declare_target:
4603  case OMPD_requires:
4604  case OMPD_declare_variant:
4605  case OMPD_begin_declare_variant:
4606  case OMPD_end_declare_variant:
4607  case OMPD_metadirective:
4608  llvm_unreachable("OpenMP Directive is not allowed");
4609  case OMPD_unknown:
4610  default:
4611  llvm_unreachable("Unknown OpenMP directive");
4612  }
4613  DSAStack->setContext(CurContext);
4614  handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4615 }
4616 
4617 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4618  return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4619 }
4620 
4622  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4623  getOpenMPCaptureRegions(CaptureRegions, DKind);
4624  return CaptureRegions.size();
4625 }
4626 
4628  Expr *CaptureExpr, bool WithInit,
4629  DeclContext *CurContext,
4630  bool AsExpression) {
4631  assert(CaptureExpr);
4632  ASTContext &C = S.getASTContext();
4633  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4634  QualType Ty = Init->getType();
4635  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4636  if (S.getLangOpts().CPlusPlus) {
4637  Ty = C.getLValueReferenceType(Ty);
4638  } else {
4639  Ty = C.getPointerType(Ty);
4640  ExprResult Res =
4641  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4642  if (!Res.isUsable())
4643  return nullptr;
4644  Init = Res.get();
4645  }
4646  WithInit = true;
4647  }
4648  auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4649  CaptureExpr->getBeginLoc());
4650  if (!WithInit)
4651  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4652  CurContext->addHiddenDecl(CED);
4654  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4655  return CED;
4656 }
4657 
4658 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4659  bool WithInit) {
4660  OMPCapturedExprDecl *CD;
4661  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4662  CD = cast<OMPCapturedExprDecl>(VD);
4663  else
4664  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4665  S.CurContext,
4666  /*AsExpression=*/false);
4667  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4668  CaptureExpr->getExprLoc());
4669 }
4670 
4671 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4672  StringRef Name) {
4673  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4674  if (!Ref) {
4676  S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4677  /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4678  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4679  CaptureExpr->getExprLoc());
4680  }
4681  ExprResult Res = Ref;
4682  if (!S.getLangOpts().CPlusPlus &&
4683  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4684  Ref->getType()->isPointerType()) {
4685  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4686  if (!Res.isUsable())
4687  return ExprError();
4688  }
4689  return S.DefaultLvalueConversion(Res.get());
4690 }
4691 
4692 namespace {
4693 // OpenMP directives parsed in this section are represented as a
4694 // CapturedStatement with an associated statement. If a syntax error
4695 // is detected during the parsing of the associated statement, the
4696 // compiler must abort processing and close the CapturedStatement.
4697 //
4698 // Combined directives such as 'target parallel' have more than one
4699 // nested CapturedStatements. This RAII ensures that we unwind out
4700 // of all the nested CapturedStatements when an error is found.
4701 class CaptureRegionUnwinderRAII {
4702 private:
4703  Sema &S;
4704  bool &ErrorFound;
4705  OpenMPDirectiveKind DKind = OMPD_unknown;
4706 
4707 public:
4708  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4709  OpenMPDirectiveKind DKind)
4710  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4711  ~CaptureRegionUnwinderRAII() {
4712  if (ErrorFound) {
4713  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4714  while (--ThisCaptureLevel >= 0)
4716  }
4717  }
4718 };
4719 } // namespace
4720 
4722  // Capture variables captured by reference in lambdas for target-based
4723  // directives.
4724  if (!CurContext->isDependentContext() &&
4725  (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4727  DSAStack->getCurrentDirective()))) {
4728  QualType Type = V->getType();
4729  if (const auto *RD = Type.getCanonicalType()
4730  .getNonReferenceType()
4731  ->getAsCXXRecordDecl()) {
4732  bool SavedForceCaptureByReferenceInTargetExecutable =
4733  DSAStack->isForceCaptureByReferenceInTargetExecutable();
4734  DSAStack->setForceCaptureByReferenceInTargetExecutable(
4735  /*V=*/true);
4736  if (RD->isLambda()) {
4737  llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4738  FieldDecl *ThisCapture;
4739  RD->getCaptureFields(Captures, ThisCapture);
4740  for (const LambdaCapture &LC : RD->captures()) {
4741  if (LC.getCaptureKind() == LCK_ByRef) {
4742  VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4743  DeclContext *VDC = VD->getDeclContext();
4744  if (!VDC->Encloses(CurContext))
4745  continue;
4746  MarkVariableReferenced(LC.getLocation(), VD);
4747  } else if (LC.getCaptureKind() == LCK_This) {
4748  QualType ThisTy = getCurrentThisType();
4749  if (!ThisTy.isNull() &&
4750  Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4751  CheckCXXThisCapture(LC.getLocation());
4752  }
4753  }
4754  }
4755  DSAStack->setForceCaptureByReferenceInTargetExecutable(
4756  SavedForceCaptureByReferenceInTargetExecutable);
4757  }
4758  }
4759 }
4760 
4762  const ArrayRef<OMPClause *> Clauses) {
4763  const OMPOrderedClause *Ordered = nullptr;
4764  const OMPOrderClause *Order = nullptr;
4765 
4766  for (const OMPClause *Clause : Clauses) {
4767  if (Clause->getClauseKind() == OMPC_ordered)
4768  Ordered = cast<OMPOrderedClause>(Clause);
4769  else if (Clause->getClauseKind() == OMPC_order) {
4770  Order = cast<OMPOrderClause>(Clause);
4771  if (Order->getKind() != OMPC_ORDER_concurrent)
4772  Order = nullptr;
4773  }
4774  if (Ordered && Order)
4775  break;
4776  }
4777 
4778  if (Ordered && Order) {
4779  S.Diag(Order->getKindKwLoc(),
4780  diag::err_omp_simple_clause_incompatible_with_ordered)
4781  << getOpenMPClauseName(OMPC_order)
4782  << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4783  << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4784  S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4785  << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4786  return true;
4787  }
4788  return false;
4789 }
4790 
4792  ArrayRef<OMPClause *> Clauses) {
4793  handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4794  /* ScopeEntry */ false);
4795  if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4796  DSAStack->getCurrentDirective() == OMPD_critical ||
4797  DSAStack->getCurrentDirective() == OMPD_section ||
4798  DSAStack->getCurrentDirective() == OMPD_master ||
4799  DSAStack->getCurrentDirective() == OMPD_masked)
4800  return S;
4801 
4802  bool ErrorFound = false;
4803  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4804  *this, ErrorFound, DSAStack->getCurrentDirective());
4805  if (!S.isUsable()) {
4806  ErrorFound = true;
4807  return StmtError();
4808  }
4809 
4810  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4811  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4812  OMPOrderedClause *OC = nullptr;
4813  OMPScheduleClause *SC = nullptr;
4816  // This is required for proper codegen.
4817  for (OMPClause *Clause : Clauses) {
4818  if (!LangOpts.OpenMPSimd &&
4819  (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4820  DSAStack->getCurrentDirective() == OMPD_target) &&
4821  Clause->getClauseKind() == OMPC_in_reduction) {
4822  // Capture taskgroup task_reduction descriptors inside the tasking regions
4823  // with the corresponding in_reduction items.
4824  auto *IRC = cast<OMPInReductionClause>(Clause);
4825  for (Expr *E : IRC->taskgroup_descriptors())
4826  if (E)
4828  }
4829  if (isOpenMPPrivate(Clause->getClauseKind()) ||
4830  Clause->getClauseKind() == OMPC_copyprivate ||
4831  (getLangOpts().OpenMPUseTLS &&
4832  getASTContext().getTargetInfo().isTLSSupported() &&
4833  Clause->getClauseKind() == OMPC_copyin)) {
4834  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4835  // Mark all variables in private list clauses as used in inner region.
4836  for (Stmt *VarRef : Clause->children()) {
4837  if (auto *E = cast_or_null<Expr>(VarRef)) {
4839  }
4840  }
4841  DSAStack->setForceVarCapturing(/*V=*/false);
4843  DSAStack->getCurrentDirective())) {
4844  assert(CaptureRegions.empty() &&
4845  "No captured regions in loop transformation directives.");
4846  } else if (CaptureRegions.size() > 1 ||
4847  CaptureRegions.back() != OMPD_unknown) {
4848  if (auto *C = OMPClauseWithPreInit::get(Clause))
4849  PICs.push_back(C);
4850  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4851  if (Expr *E = C->getPostUpdateExpr())
4853  }
4854  }
4855  if (Clause->getClauseKind() == OMPC_schedule)
4856  SC = cast<OMPScheduleClause>(Clause);
4857  else if (Clause->getClauseKind() == OMPC_ordered)
4858  OC = cast<OMPOrderedClause>(Clause);
4859  else if (Clause->getClauseKind() == OMPC_linear)
4860  LCs.push_back(cast<OMPLinearClause>(Clause));
4861  }
4862  // Capture allocator expressions if used.
4863  for (Expr *E : DSAStack->getInnerAllocators())
4865  // OpenMP, 2.7.1 Loop Construct, Restrictions
4866  // The nonmonotonic modifier cannot be specified if an ordered clause is
4867  // specified.
4868  if (SC &&
4869  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4870  SC->getSecondScheduleModifier() ==
4871  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4872  OC) {
4873  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4876  diag::err_omp_simple_clause_incompatible_with_ordered)
4877  << getOpenMPClauseName(OMPC_schedule)
4878  << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4879  OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4880  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4881  ErrorFound = true;
4882  }
4883  // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4884  // If an order(concurrent) clause is present, an ordered clause may not appear
4885  // on the same directive.
4886  if (checkOrderedOrderSpecified(*this, Clauses))
4887  ErrorFound = true;
4888  if (!LCs.empty() && OC && OC->getNumForLoops()) {
4889  for (const OMPLinearClause *C : LCs) {
4890  Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4891  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4892  }
4893  ErrorFound = true;
4894  }
4895  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4896  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4897  OC->getNumForLoops()) {
4898  Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4899  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4900  ErrorFound = true;
4901  }
4902  if (ErrorFound) {
4903  return StmtError();
4904  }
4905  StmtResult SR = S;
4906  unsigned CompletedRegions = 0;
4907  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4908  // Mark all variables in private list clauses as used in inner region.
4909  // Required for proper codegen of combined directives.
4910  // TODO: add processing for other clauses.
4911  if (ThisCaptureRegion != OMPD_unknown) {
4912  for (const clang::OMPClauseWithPreInit *C : PICs) {
4913  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4914  // Find the particular capture region for the clause if the
4915  // directive is a combined one with multiple capture regions.
4916  // If the directive is not a combined one, the capture region
4917  // associated with the clause is OMPD_unknown and is generated
4918  // only once.
4919  if (CaptureRegion == ThisCaptureRegion ||
4920  CaptureRegion == OMPD_unknown) {
4921  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4922  for (Decl *D : DS->decls())
4923  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4924  }
4925  }
4926  }
4927  }
4928  if (ThisCaptureRegion == OMPD_target) {
4929  // Capture allocator traits in the target region. They are used implicitly
4930  // and, thus, are not captured by default.
4931  for (OMPClause *C : Clauses) {
4932  if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4933  for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4934  ++I) {
4935  OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4936  if (Expr *E = D.AllocatorTraits)
4938  }
4939  continue;
4940  }
4941  }
4942  }
4943  if (ThisCaptureRegion == OMPD_parallel) {
4944  // Capture temp arrays for inscan reductions and locals in aligned
4945  // clauses.
4946  for (OMPClause *C : Clauses) {
4947  if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4948  if (RC->getModifier() != OMPC_REDUCTION_inscan)
4949  continue;
4950  for (Expr *E : RC->copy_array_temps())
4952  }
4953  if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4954  for (Expr *E : AC->varlists())
4956  }
4957  }
4958  }
4959  if (++CompletedRegions == CaptureRegions.size())
4960  DSAStack->setBodyComplete();
4961  SR = ActOnCapturedRegionEnd(SR.get());
4962  }
4963  return SR;
4964 }
4965 
4966 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4967  OpenMPDirectiveKind CancelRegion,
4968  SourceLocation StartLoc) {
4969  // CancelRegion is only needed for cancel and cancellation_point.
4970  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4971  return false;
4972 
4973  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4974  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4975  return false;
4976 
4977  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4978  << getOpenMPDirectiveName(CancelRegion);
4979  return true;
4980 }
4981 
4982 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4983  OpenMPDirectiveKind CurrentRegion,
4984  const DeclarationNameInfo &CurrentName,
4985  OpenMPDirectiveKind CancelRegion,
4986  OpenMPBindClauseKind BindKind,
4987  SourceLocation StartLoc) {
4988  if (Stack->getCurScope()) {
4989  OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4990  OpenMPDirectiveKind OffendingRegion = ParentRegion;
4991  bool NestingProhibited = false;
4992  bool CloseNesting = true;
4993  bool OrphanSeen = false;
4994  enum {
4995  NoRecommend,
4996  ShouldBeInParallelRegion,
4997  ShouldBeInOrderedRegion,
4998  ShouldBeInTargetRegion,
4999  ShouldBeInTeamsRegion,
5000  ShouldBeInLoopSimdRegion,
5001  } Recommend = NoRecommend;
5002  if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5003  CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5004  CurrentRegion != OMPD_parallel &&
5005  !isOpenMPCombinedParallelADirective(CurrentRegion)) {
5006  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
5007  << getOpenMPDirectiveName(CurrentRegion);
5008  return true;
5009  }
5010  if (isOpenMPSimdDirective(ParentRegion) &&
5011  ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5012  (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5013  CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5014  CurrentRegion != OMPD_scan))) {
5015  // OpenMP [2.16, Nesting of Regions]
5016  // OpenMP constructs may not be nested inside a simd region.
5017  // OpenMP [2.8.1,simd Construct, Restrictions]
5018  // An ordered construct with the simd clause is the only OpenMP
5019  // construct that can appear in the simd region.
5020  // Allowing a SIMD construct nested in another SIMD construct is an
5021  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
5022  // message.
5023  // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
5024  // The only OpenMP constructs that can be encountered during execution of
5025  // a simd region are the atomic construct, the loop construct, the simd
5026  // construct and the ordered construct with the simd clause.
5027  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5028  ? diag::err_omp_prohibited_region_simd
5029  : diag::warn_omp_nesting_simd)
5030  << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5031  return CurrentRegion != OMPD_simd;
5032  }
5033  if (ParentRegion == OMPD_atomic) {
5034  // OpenMP [2.16, Nesting of Regions]
5035  // OpenMP constructs may not be nested inside an atomic region.
5036  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5037  return true;
5038  }
5039  if (CurrentRegion == OMPD_section) {
5040  // OpenMP [2.7.2, sections Construct, Restrictions]
5041  // Orphaned section directives are prohibited. That is, the section
5042  // directives must appear within the sections construct and must not be
5043  // encountered elsewhere in the sections region.
5044  if (ParentRegion != OMPD_sections &&
5045  ParentRegion != OMPD_parallel_sections) {
5046  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5047  << (ParentRegion != OMPD_unknown)
5048  << getOpenMPDirectiveName(ParentRegion);
5049  return true;
5050  }
5051  return false;
5052  }
5053  // Allow some constructs (except teams and cancellation constructs) to be
5054  // orphaned (they could be used in functions, called from OpenMP regions
5055  // with the required preconditions).
5056  if (ParentRegion == OMPD_unknown &&
5057  !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5058  CurrentRegion != OMPD_cancellation_point &&
5059  CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5060  return false;
5061  if (CurrentRegion == OMPD_cancellation_point ||
5062  CurrentRegion == OMPD_cancel) {
5063  // OpenMP [2.16, Nesting of Regions]
5064  // A cancellation point construct for which construct-type-clause is
5065  // taskgroup must be nested inside a task construct. A cancellation
5066  // point construct for which construct-type-clause is not taskgroup must
5067  // be closely nested inside an OpenMP construct that matches the type
5068  // specified in construct-type-clause.
5069  // A cancel construct for which construct-type-clause is taskgroup must be
5070  // nested inside a task construct. A cancel construct for which
5071  // construct-type-clause is not taskgroup must be closely nested inside an
5072  // OpenMP construct that matches the type specified in
5073  // construct-type-clause.
5074  NestingProhibited =
5075  !((CancelRegion == OMPD_parallel &&
5076  (ParentRegion == OMPD_parallel ||
5077  ParentRegion == OMPD_target_parallel)) ||
5078  (CancelRegion == OMPD_for &&
5079  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5080  ParentRegion == OMPD_target_parallel_for ||
5081  ParentRegion == OMPD_distribute_parallel_for ||
5082  ParentRegion == OMPD_teams_distribute_parallel_for ||
5083  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5084  (CancelRegion == OMPD_taskgroup &&
5085  (ParentRegion == OMPD_task ||
5086  (SemaRef.getLangOpts().OpenMP >= 50 &&
5087  (ParentRegion == OMPD_taskloop ||
5088  ParentRegion == OMPD_master_taskloop ||
5089  ParentRegion == OMPD_masked_taskloop ||
5090  ParentRegion == OMPD_parallel_masked_taskloop ||
5091  ParentRegion == OMPD_parallel_master_taskloop)))) ||
5092  (CancelRegion == OMPD_sections &&
5093  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5094  ParentRegion == OMPD_parallel_sections)));
5095  OrphanSeen = ParentRegion == OMPD_unknown;
5096  } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5097  // OpenMP 5.1 [2.22, Nesting of Regions]
5098  // A masked region may not be closely nested inside a worksharing, loop,
5099  // atomic, task, or taskloop region.
5100  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5101  isOpenMPGenericLoopDirective(ParentRegion) ||
5102  isOpenMPTaskingDirective(ParentRegion);
5103  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5104  // OpenMP [2.16, Nesting of Regions]
5105  // A critical region may not be nested (closely or otherwise) inside a
5106  // critical region with the same name. Note that this restriction is not
5107  // sufficient to prevent deadlock.
5108  SourceLocation PreviousCriticalLoc;
5109  bool DeadLock = Stack->hasDirective(
5110  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5111  const DeclarationNameInfo &DNI,
5112  SourceLocation Loc) {
5113  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5114  PreviousCriticalLoc = Loc;
5115  return true;
5116  }
5117  return false;
5118  },
5119  false /* skip top directive */);
5120  if (DeadLock) {
5121  SemaRef.Diag(StartLoc,
5122  diag::err_omp_prohibited_region_critical_same_name)
5123  << CurrentName.getName();
5124  if (PreviousCriticalLoc.isValid())
5125  SemaRef.Diag(PreviousCriticalLoc,
5126  diag::note_omp_previous_critical_region);
5127  return true;
5128  }
5129  } else if (CurrentRegion == OMPD_barrier) {
5130  // OpenMP 5.1 [2.22, Nesting of Regions]
5131  // A barrier region may not be closely nested inside a worksharing, loop,
5132  // task, taskloop, critical, ordered, atomic, or masked region.
5133  NestingProhibited =
5134  isOpenMPWorksharingDirective(ParentRegion) ||
5135  isOpenMPGenericLoopDirective(ParentRegion) ||
5136  isOpenMPTaskingDirective(ParentRegion) ||
5137  ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5138  ParentRegion == OMPD_parallel_master ||
5139  ParentRegion == OMPD_parallel_masked ||
5140  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5141  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5142  !isOpenMPParallelDirective(CurrentRegion) &&
5143  !isOpenMPTeamsDirective(CurrentRegion)) {
5144  // OpenMP 5.1 [2.22, Nesting of Regions]
5145  // A loop region that binds to a parallel region or a worksharing region
5146  // may not be closely nested inside a worksharing, loop, task, taskloop,
5147  // critical, ordered, atomic, or masked region.
5148  NestingProhibited =
5149  isOpenMPWorksharingDirective(ParentRegion) ||
5150  isOpenMPGenericLoopDirective(ParentRegion) ||
5151  isOpenMPTaskingDirective(ParentRegion) ||
5152  ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5153  ParentRegion == OMPD_parallel_master ||
5154  ParentRegion == OMPD_parallel_masked ||
5155  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5156  Recommend = ShouldBeInParallelRegion;
5157  } else if (CurrentRegion == OMPD_ordered) {
5158  // OpenMP [2.16, Nesting of Regions]
5159  // An ordered region may not be closely nested inside a critical,
5160  // atomic, or explicit task region.
5161  // An ordered region must be closely nested inside a loop region (or
5162  // parallel loop region) with an ordered clause.
5163  // OpenMP [2.8.1,simd Construct, Restrictions]
5164  // An ordered construct with the simd clause is the only OpenMP construct
5165  // that can appear in the simd region.
5166  NestingProhibited = ParentRegion == OMPD_critical ||
5167  isOpenMPTaskingDirective(ParentRegion) ||
5168  !(isOpenMPSimdDirective(ParentRegion) ||
5169  Stack->isParentOrderedRegion());
5170  Recommend = ShouldBeInOrderedRegion;
5171  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5172  // OpenMP [2.16, Nesting of Regions]
5173  // If specified, a teams construct must be contained within a target
5174  // construct.
5175  NestingProhibited =
5176  (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5177  (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5178  ParentRegion != OMPD_target);
5179  OrphanSeen = ParentRegion == OMPD_unknown;
5180  Recommend = ShouldBeInTargetRegion;
5181  } else if (CurrentRegion == OMPD_scan) {
5182  // OpenMP [2.16, Nesting of Regions]
5183  // If specified, a teams construct must be contained within a target
5184  // construct.
5185  NestingProhibited =
5186  SemaRef.LangOpts.OpenMP < 50 ||
5187  (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5188  ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5189  ParentRegion != OMPD_parallel_for_simd);
5190  OrphanSeen = ParentRegion == OMPD_unknown;
5191  Recommend = ShouldBeInLoopSimdRegion;
5192  }
5193  if (!NestingProhibited &&
5194  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5195  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5196  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5197  // OpenMP [5.1, 2.22, Nesting of Regions]
5198  // distribute, distribute simd, distribute parallel worksharing-loop,
5199  // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5200  // including any parallel regions arising from combined constructs,
5201  // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5202  // only OpenMP regions that may be strictly nested inside the teams
5203  // region.
5204  //
5205  // As an extension, we permit atomic within teams as well.
5206  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5207  !isOpenMPDistributeDirective(CurrentRegion) &&
5208  CurrentRegion != OMPD_loop &&
5209  !(SemaRef.getLangOpts().OpenMPExtensions &&
5210  CurrentRegion == OMPD_atomic);
5211  Recommend = ShouldBeInParallelRegion;
5212  }
5213  if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5214  // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5215  // If the bind clause is present on the loop construct and binding is
5216  // teams then the corresponding loop region must be strictly nested inside
5217  // a teams region.
5218  NestingProhibited = BindKind == OMPC_BIND_teams &&
5219  ParentRegion != OMPD_teams &&
5220  ParentRegion != OMPD_target_teams;
5221  Recommend = ShouldBeInTeamsRegion;
5222  }
5223  if (!NestingProhibited &&
5224  isOpenMPNestingDistributeDirective(CurrentRegion)) {
5225  // OpenMP 4.5 [2.17 Nesting of Regions]
5226  // The region associated with the distribute construct must be strictly
5227  // nested inside a teams region
5228  NestingProhibited =
5229  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5230  Recommend = ShouldBeInTeamsRegion;
5231  }
5232  if (!NestingProhibited &&
5233  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5234  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5235  // OpenMP 4.5 [2.17 Nesting of Regions]
5236  // If a target, target update, target data, target enter data, or
5237  // target exit data construct is encountered during execution of a
5238  // target region, the behavior is unspecified.
5239  NestingProhibited = Stack->hasDirective(
5240  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5241  SourceLocation) {
5243  OffendingRegion = K;
5244  return true;
5245  }
5246  return false;
5247  },
5248  false /* don't skip top directive */);
5249  CloseNesting = false;
5250  }
5251  if (NestingProhibited) {
5252  if (OrphanSeen) {
5253  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5254  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5255  } else {
5256  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5257  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5258  << Recommend << getOpenMPDirectiveName(CurrentRegion);
5259  }
5260  return true;
5261  }
5262  }
5263  return false;
5264 }
5265 
5268  unsigned operator()(argument_type DK) { return unsigned(DK); }
5269 };
5271  ArrayRef<OMPClause *> Clauses,
5272  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5273  bool ErrorFound = false;
5274  unsigned NamedModifiersNumber = 0;
5275  llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5276  FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5277  SmallVector<SourceLocation, 4> NameModifierLoc;
5278  for (const OMPClause *C : Clauses) {
5279  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5280  // At most one if clause without a directive-name-modifier can appear on
5281  // the directive.
5282  OpenMPDirectiveKind CurNM = IC->getNameModifier();
5283  if (FoundNameModifiers[CurNM]) {
5284  S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5285  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5286  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5287  ErrorFound = true;
5288  } else if (CurNM != OMPD_unknown) {
5289  NameModifierLoc.push_back(IC->getNameModifierLoc());
5290  ++NamedModifiersNumber;
5291  }
5292  FoundNameModifiers[CurNM] = IC;
5293  if (CurNM == OMPD_unknown)
5294  continue;
5295  // Check if the specified name modifier is allowed for the current
5296  // directive.
5297  // At most one if clause with the particular directive-name-modifier can
5298  // appear on the directive.
5299  if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5300  S.Diag(IC->getNameModifierLoc(),
5301  diag::err_omp_wrong_if_directive_name_modifier)
5302  << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5303  ErrorFound = true;
5304  }
5305  }
5306  }
5307  // If any if clause on the directive includes a directive-name-modifier then
5308  // all if clauses on the directive must include a directive-name-modifier.
5309  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5310  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5311  S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5312  diag::err_omp_no_more_if_clause);
5313  } else {
5314  std::string Values;
5315  std::string Sep(", ");
5316  unsigned AllowedCnt = 0;
5317  unsigned TotalAllowedNum =
5318  AllowedNameModifiers.size() - NamedModifiersNumber;
5319  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5320  ++Cnt) {
5321  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5322  if (!FoundNameModifiers[NM]) {
5323  Values += "'";
5324  Values += getOpenMPDirectiveName(NM);
5325  Values += "'";
5326  if (AllowedCnt + 2 == TotalAllowedNum)
5327  Values += " or ";
5328  else if (AllowedCnt + 1 != TotalAllowedNum)
5329  Values += Sep;
5330  ++AllowedCnt;
5331  }
5332  }
5333  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5334  diag::err_omp_unnamed_if_clause)
5335  << (TotalAllowedNum > 1) << Values;
5336  }
5337  for (SourceLocation Loc : NameModifierLoc) {
5338  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5339  }
5340  ErrorFound = true;
5341  }
5342  return ErrorFound;
5343 }
5344 
5345 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5346  SourceLocation &ELoc,
5347  SourceRange &ERange,
5348  bool AllowArraySection,
5349  StringRef DiagType) {
5350  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5352  return std::make_pair(nullptr, true);
5353 
5354  // OpenMP [3.1, C/C++]
5355  // A list item is a variable name.
5356  // OpenMP [2.9.3.3, Restrictions, p.1]
5357  // A variable that is part of another variable (as an array or
5358  // structure element) cannot appear in a private clause.
5359  RefExpr = RefExpr->IgnoreParens();
5360  enum {
5361  NoArrayExpr = -1,
5362  ArraySubscript = 0,
5363  OMPArraySection = 1
5364  } IsArrayExpr = NoArrayExpr;
5365  if (AllowArraySection) {
5366  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5367  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5368  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5369  Base = TempASE->getBase()->IgnoreParenImpCasts();
5370  RefExpr = Base;
5371  IsArrayExpr = ArraySubscript;
5372  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5373  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5374  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5375  Base = TempOASE->getBase()->IgnoreParenImpCasts();
5376  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5377  Base = TempASE->getBase()->IgnoreParenImpCasts();
5378  RefExpr = Base;
5379  IsArrayExpr = OMPArraySection;
5380  }
5381  }
5382  ELoc = RefExpr->getExprLoc();
5383  ERange = RefExpr->getSourceRange();
5384  RefExpr = RefExpr->IgnoreParenImpCasts();
5385  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5386  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5387  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5388  (S.getCurrentThisType().isNull() || !ME ||
5389  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5390  !isa<FieldDecl>(ME->getMemberDecl()))) {
5391  if (IsArrayExpr != NoArrayExpr) {
5392  S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5393  << IsArrayExpr << ERange;
5394  } else if (!DiagType.empty()) {
5395  unsigned DiagSelect = S.getLangOpts().CPlusPlus
5396  ? (S.getCurrentThisType().isNull() ? 1 : 2)
5397  : 0;
5398  S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5399  << DiagSelect << DiagType << ERange;
5400  } else {
5401  S.Diag(ELoc,
5402  AllowArraySection
5403  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5404  : diag::err_omp_expected_var_name_member_expr)
5405  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5406  }
5407  return std::make_pair(nullptr, false);
5408  }
5409  return std::make_pair(
5410  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5411 }
5412 
5413 namespace {
5414 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5415 /// target regions.
5416 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5417  DSAStackTy *S = nullptr;
5418 
5419 public:
5420  bool VisitDeclRefExpr(const DeclRefExpr *E) {
5421  return S->isUsesAllocatorsDecl(E->getDecl())
5422  .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5423  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5424  }
5425  bool VisitStmt(const Stmt *S) {
5426  for (const Stmt *Child : S->children()) {
5427  if (Child && Visit(Child))
5428  return true;
5429  }
5430  return false;
5431  }
5432  explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5433 };
5434 } // namespace
5435 
5436 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5437  ArrayRef<OMPClause *> Clauses) {
5438  assert(!S.CurContext->isDependentContext() &&
5439  "Expected non-dependent context.");
5440  auto AllocateRange =
5441  llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5442  llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5443  auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5444  return isOpenMPPrivate(C->getClauseKind());
5445  });
5446  for (OMPClause *Cl : PrivateRange) {
5448  if (Cl->getClauseKind() == OMPC_private) {
5449  auto *PC = cast<OMPPrivateClause>(Cl);
5450  I = PC->private_copies().begin();
5451  It = PC->varlist_begin();
5452  Et = PC->varlist_end();
5453  } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5454  auto *PC = cast<OMPFirstprivateClause>(Cl);
5455  I = PC->private_copies().begin();
5456  It = PC->varlist_begin();
5457  Et = PC->varlist_end();
5458  } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5459  auto *PC = cast<OMPLastprivateClause>(Cl);
5460  I = PC->private_copies().begin();
5461  It = PC->varlist_begin();
5462  Et = PC->varlist_end();
5463  } else if (Cl->getClauseKind() == OMPC_linear) {
5464  auto *PC = cast<OMPLinearClause>(Cl);
5465  I = PC->privates().begin();
5466  It = PC->varlist_begin();
5467  Et = PC->varlist_end();
5468  } else if (Cl->getClauseKind() == OMPC_reduction) {
5469  auto *PC = cast<OMPReductionClause>(Cl);
5470  I = PC->privates().begin();
5471  It = PC->varlist_begin();
5472  Et = PC->varlist_end();
5473  } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5474  auto *PC = cast<OMPTaskReductionClause>(Cl);
5475  I = PC->privates().begin();
5476  It = PC->varlist_begin();
5477  Et = PC->varlist_end();
5478  } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5479  auto *PC = cast<OMPInReductionClause>(Cl);
5480  I = PC->privates().begin();
5481  It = PC->varlist_begin();
5482  Et = PC->varlist_end();
5483  } else {
5484  llvm_unreachable("Expected private clause.");
5485  }
5486  for (Expr *E : llvm::make_range(It, Et)) {
5487  if (!*I) {
5488  ++I;
5489  continue;
5490  }
5491  SourceLocation ELoc;
5492  SourceRange ERange;
5493  Expr *SimpleRefExpr = E;
5494  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5495  /*AllowArraySection=*/true);
5496  DeclToCopy.try_emplace(Res.first,
5497  cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5498  ++I;
5499  }
5500  }
5501  for (OMPClause *C : AllocateRange) {
5502  auto *AC = cast<OMPAllocateClause>(C);
5503  if (S.getLangOpts().OpenMP >= 50 &&
5504  !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5505  isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5506  AC->getAllocator()) {
5507  Expr *Allocator = AC->getAllocator();
5508  // OpenMP, 2.12.5 target Construct
5509  // Memory allocators that do not appear in a uses_allocators clause cannot
5510  // appear as an allocator in an allocate clause or be used in the target
5511  // region unless a requires directive with the dynamic_allocators clause
5512  // is present in the same compilation unit.
5513  AllocatorChecker Checker(Stack);
5514  if (Checker.Visit(Allocator))
5515  S.Diag(Allocator->getExprLoc(),
5516  diag::err_omp_allocator_not_in_uses_allocators)
5517  << Allocator->getSourceRange();
5518  }
5519  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5520  getAllocatorKind(S, Stack, AC->getAllocator());
5521  // OpenMP, 2.11.4 allocate Clause, Restrictions.
5522  // For task, taskloop or target directives, allocation requests to memory
5523  // allocators with the trait access set to thread result in unspecified
5524  // behavior.
5525  if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5526  (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5527  isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5528  S.Diag(AC->getAllocator()->getExprLoc(),
5529  diag::warn_omp_allocate_thread_on_task_target_directive)
5530  << getOpenMPDirectiveName(Stack->getCurrentDirective());
5531  }
5532  for (Expr *E : AC->varlists()) {
5533  SourceLocation ELoc;
5534  SourceRange ERange;
5535  Expr *SimpleRefExpr = E;
5536  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5537  ValueDecl *VD = Res.first;
5538  DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5539  if (!isOpenMPPrivate(Data.CKind)) {
5540  S.Diag(E->getExprLoc(),
5541  diag::err_omp_expected_private_copy_for_allocate);
5542  continue;
5543  }
5544  VarDecl *PrivateVD = DeclToCopy[VD];
5545  if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5546  AllocatorKind, AC->getAllocator()))
5547  continue;
5548  // Placeholder until allocate clause supports align modifier.
5549  Expr *Alignment = nullptr;
5550  applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5551  Alignment, E->getSourceRange());
5552  }
5553  }
5554 }
5555 
5556 namespace {
5557 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5558 ///
5559 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5560 /// context. DeclRefExpr used inside the new context are changed to refer to the
5561 /// captured variable instead.
5562 class CaptureVars : public TreeTransform<CaptureVars> {
5563  using BaseTransform = TreeTransform<CaptureVars>;
5564 
5565 public:
5566  CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5567 
5568  bool AlwaysRebuild() { return true; }
5569 };
5570 } // namespace
5571 
5572 static VarDecl *precomputeExpr(Sema &Actions,
5573  SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5574  StringRef Name) {
5575  Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5576  VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5577  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5578  auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5579  Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5580  Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5581  BodyStmts.push_back(NewDeclStmt);
5582  return NewVar;
5583 }
5584 
5585 /// Create a closure that computes the number of iterations of a loop.
5586 ///
5587 /// \param Actions The Sema object.
5588 /// \param LogicalTy Type for the logical iteration number.
5589 /// \param Rel Comparison operator of the loop condition.
5590 /// \param StartExpr Value of the loop counter at the first iteration.
5591 /// \param StopExpr Expression the loop counter is compared against in the loop
5592 /// condition. \param StepExpr Amount of increment after each iteration.
5593 ///
5594 /// \return Closure (CapturedStmt) of the distance calculation.
5595 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5597  Expr *StartExpr, Expr *StopExpr,
5598  Expr *StepExpr) {
5599  ASTContext &Ctx = Actions.getASTContext();
5600  TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5601 
5602  // Captured regions currently don't support return values, we use an
5603  // out-parameter instead. All inputs are implicit captures.
5604  // TODO: Instead of capturing each DeclRefExpr occurring in
5605  // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5606  QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5607  Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5608  {StringRef(), QualType()}};
5609  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5610 
5611  Stmt *Body;
5612  {
5613  Sema::CompoundScopeRAII CompoundScope(Actions);
5614  CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5615 
5616  // Get the LValue expression for the result.
5617  ImplicitParamDecl *DistParam = CS->getParam(0);
5618  DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5619  DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5620 
5621  SmallVector<Stmt *, 4> BodyStmts;
5622 
5623  // Capture all referenced variable references.
5624  // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5625  // CapturedStmt, we could compute them before and capture the result, to be
5626  // used jointly with the LoopVar function.
5627  VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5628  VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5629  VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5630  auto BuildVarRef = [&](VarDecl *VD) {
5631  return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5632  };
5633 
5635  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5637  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5638  Expr *Dist;
5639  if (Rel == BO_NE) {
5640  // When using a != comparison, the increment can be +1 or -1. This can be
5641  // dynamic at runtime, so we need to check for the direction.
5642  Expr *IsNegStep = AssertSuccess(
5643  Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5644 
5645  // Positive increment.
5646  Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5647  nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5648  ForwardRange = AssertSuccess(
5649  Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5650  Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5651  nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5652 
5653  // Negative increment.
5654  Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5655  nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5656  BackwardRange = AssertSuccess(
5657  Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5658  Expr *NegIncAmount = AssertSuccess(
5659  Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5660  Expr *BackwardDist = AssertSuccess(
5661  Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5662 
5663  // Use the appropriate case.
5664  Dist = AssertSuccess(Actions.ActOnConditionalOp(
5665  {}, {}, IsNegStep, BackwardDist, ForwardDist));
5666  } else {
5667  assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5668  "Expected one of these relational operators");
5669 
5670  // We can derive the direction from any other comparison operator. It is
5671  // non well-formed OpenMP if Step increments/decrements in the other
5672  // directions. Whether at least the first iteration passes the loop
5673  // condition.
5674  Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5675  nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5676 
5677  // Compute the range between first and last counter value.
5678  Expr *Range;
5679  if (Rel == BO_GE || Rel == BO_GT)
5680  Range = AssertSuccess(Actions.BuildBinOp(
5681  nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5682  else
5683  Range = AssertSuccess(Actions.BuildBinOp(
5684  nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5685 
5686  // Ensure unsigned range space.
5687  Range =
5688  AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5689 
5690  if (Rel == BO_LE || Rel == BO_GE) {
5691  // Add one to the range if the relational operator is inclusive.
5692  Range =
5693  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5694  }
5695 
5696  // Divide by the absolute step amount. If the range is not a multiple of
5697  // the step size, rounding-up the effective upper bound ensures that the
5698  // last iteration is included.
5699  // Note that the rounding-up may cause an overflow in a temporry that
5700  // could be avoided, but would have occurred in a C-style for-loop as well.
5701  Expr *Divisor = BuildVarRef(NewStep);
5702  if (Rel == BO_GE || Rel == BO_GT)
5703  Divisor =
5704  AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5705  Expr *DivisorMinusOne =
5706  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5707  Expr *RangeRoundUp = AssertSuccess(
5708  Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5709  Dist = AssertSuccess(
5710  Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5711 
5712  // If there is not at least one iteration, the range contains garbage. Fix
5713  // to zero in this case.
5714  Dist = AssertSuccess(
5715  Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5716  }
5717 
5718  // Assign the result to the out-parameter.
5719  Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5720  Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5721  BodyStmts.push_back(ResultAssign);
5722 
5723  Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5724  }
5725 
5726  return cast<CapturedStmt>(
5727  AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5728 }
5729 
5730 /// Create a closure that computes the loop variable from the logical iteration
5731 /// number.
5732 ///
5733 /// \param Actions The Sema object.
5734 /// \param LoopVarTy Type for the loop variable used for result value.
5735 /// \param LogicalTy Type for the logical iteration number.
5736 /// \param StartExpr Value of the loop counter at the first iteration.
5737 /// \param Step Amount of increment after each iteration.
5738 /// \param Deref Whether the loop variable is a dereference of the loop
5739 /// counter variable.
5740 ///
5741 /// \return Closure (CapturedStmt) of the loop value calculation.
5742 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5743  QualType LogicalTy,
5744  DeclRefExpr *StartExpr, Expr *Step,
5745  bool Deref) {
5746  ASTContext &Ctx = Actions.getASTContext();
5747 
5748  // Pass the result as an out-parameter. Passing as return value would require
5749  // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5750  // invoke a copy constructor.
5751  QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5752  Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5753  {"Logical", LogicalTy},
5754  {StringRef(), QualType()}};
5755  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5756 
5757  // Capture the initial iterator which represents the LoopVar value at the
5758  // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5759  // it in every iteration, capture it by value before it is modified.
5760  VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5761  bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5763  (void)Invalid;
5764  assert(!Invalid && "Expecting capture-by-value to work.");
5765 
5766  Expr *Body;
5767  {
5768  Sema::CompoundScopeRAII CompoundScope(Actions);
5769  auto *CS = cast<CapturedDecl>(Actions.CurContext);
5770 
5771  ImplicitParamDecl *TargetParam = CS->getParam(0);
5772  DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5773  TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5774  ImplicitParamDecl *IndvarParam = CS->getParam(1);
5775  DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5776  IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5777 
5778  // Capture the Start expression.
5779  CaptureVars Recap(Actions);
5780  Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5781  Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5782 
5783  Expr *Skip = AssertSuccess(
5784  Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5785  // TODO: Explicitly cast to the iterator's difference_type instead of
5786  // relying on implicit conversion.
5787  Expr *Advanced =
5788  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5789 
5790  if (Deref) {
5791  // For range-based for-loops convert the loop counter value to a concrete
5792  // loop variable value by dereferencing the iterator.
5793  Advanced =
5794  AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5795  }
5796 
5797  // Assign the result to the output parameter.
5798  Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5799  BO_Assign, TargetRef, Advanced));
5800  }
5801  return cast<CapturedStmt>(
5802  AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5803 }
5804 
5806  ASTContext &Ctx = getASTContext();
5807 
5808  // Extract the common elements of ForStmt and CXXForRangeStmt:
5809  // Loop variable, repeat condition, increment
5810  Expr *Cond, *Inc;
5811  VarDecl *LIVDecl, *LUVDecl;
5812  if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5813  Stmt *Init = For->getInit();
5814  if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5815  // For statement declares loop variable.
5816  LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5817  } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5818  // For statement reuses variable.
5819  assert(LCAssign->getOpcode() == BO_Assign &&
5820  "init part must be a loop variable assignment");
5821  auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5822  LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5823  } else
5824  llvm_unreachable("Cannot determine loop variable");
5825  LUVDecl = LIVDecl;
5826 
5827  Cond = For->getCond();
5828  Inc = For->getInc();
5829  } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5830  DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5831  LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5832  LUVDecl = RangeFor->getLoopVariable();
5833 
5834  Cond = RangeFor->getCond();
5835  Inc = RangeFor->getInc();
5836  } else
5837  llvm_unreachable("unhandled kind of loop");
5838 
5839  QualType CounterTy = LIVDecl->getType();
5840  QualType LVTy = LUVDecl->getType();
5841 
5842  // Analyze the loop condition.
5843  Expr *LHS, *RHS;
5844  BinaryOperator::Opcode CondRel;
5845  Cond = Cond->IgnoreImplicit();
5846  if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5847  LHS = CondBinExpr->getLHS();
5848  RHS = CondBinExpr->getRHS();
5849  CondRel = CondBinExpr->getOpcode();
5850  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5851  assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5852  LHS = CondCXXOp->getArg(0);
5853  RHS = CondCXXOp->getArg(1);
5854  switch (CondCXXOp->getOperator()) {
5855  case OO_ExclaimEqual:
5856  CondRel = BO_NE;
5857  break;
5858  case OO_Less:
5859  CondRel = BO_LT;
5860  break;
5861  case OO_LessEqual:
5862  CondRel = BO_LE;
5863  break;
5864  case OO_Greater:
5865  CondRel = BO_GT;
5866  break;
5867  case OO_GreaterEqual:
5868  CondRel = BO_GE;
5869  break;
5870  default:
5871  llvm_unreachable("unexpected iterator operator");
5872  }
5873  } else
5874  llvm_unreachable("unexpected loop condition");
5875 
5876  // Normalize such that the loop counter is on the LHS.
5877  if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5878  cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5879  std::swap(LHS, RHS);
5880  CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5881  }
5882  auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5883 
5884  // Decide the bit width for the logical iteration counter. By default use the
5885  // unsigned ptrdiff_t integer size (for iterators and pointers).
5886  // TODO: For iterators, use iterator::difference_type,
5887  // std::iterator_traits<>::difference_type or decltype(it - end).
5888  QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5889  if (CounterTy->isIntegerType()) {
5890  unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5891  LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5892  }
5893 
5894  // Analyze the loop increment.
5895  Expr *Step;
5896  if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5897  int Direction;
5898  switch (IncUn->getOpcode()) {
5899  case UO_PreInc:
5900  case UO_PostInc:
5901  Direction = 1;
5902  break;
5903  case UO_PreDec:
5904  case UO_PostDec:
5905  Direction = -1;
5906  break;
5907  default:
5908  llvm_unreachable("unhandled unary increment operator");
5909  }
5910  Step = IntegerLiteral::Create(
5911  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5912  } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5913  if (IncBin->getOpcode() == BO_AddAssign) {
5914  Step = IncBin->getRHS();
5915  } else if (IncBin->getOpcode() == BO_SubAssign) {
5916  Step =
5917  AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5918  } else
5919  llvm_unreachable("unhandled binary increment operator");
5920  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5921  switch (CondCXXOp->getOperator()) {
5922  case OO_PlusPlus:
5923  Step = IntegerLiteral::Create(
5924  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5925  break;
5926  case OO_MinusMinus:
5927  Step = IntegerLiteral::Create(
5928  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5929  break;
5930  case OO_PlusEqual:
5931  Step = CondCXXOp->getArg(1);
5932  break;
5933  case OO_MinusEqual:
5934  Step = AssertSuccess(
5935  BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5936  break;
5937  default:
5938  llvm_unreachable("unhandled overloaded increment operator");
5939  }
5940  } else
5941  llvm_unreachable("unknown increment expression");
5942 
5943  CapturedStmt *DistanceFunc =
5944  buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5945  CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5946  *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5947  DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5948  {}, nullptr, nullptr, {}, nullptr);
5949  return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5950  LoopVarFunc, LVRef);
5951 }
5952 
5954  // Handle a literal loop.
5955  if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5956  return ActOnOpenMPCanonicalLoop(AStmt);
5957 
5958  // If not a literal loop, it must be the result of a loop transformation.
5959  OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5960  assert(
5962  "Loop transformation directive expected");
5963  return LoopTransform;
5964 }
5965 
5966 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5967  CXXScopeSpec &MapperIdScopeSpec,
5968  const DeclarationNameInfo &MapperId,
5969  QualType Type,
5970  Expr *UnresolvedMapper);
5971 
5972 /// Perform DFS through the structure/class data members trying to find
5973 /// member(s) with user-defined 'default' mapper and generate implicit map
5974 /// clauses for such members with the found 'default' mapper.
5975 static void
5977  SmallVectorImpl<OMPClause *> &Clauses) {
5978  // Check for the deault mapper for data members.
5979  if (S.getLangOpts().OpenMP < 50)
5980  return;
5981  SmallVector<OMPClause *, 4> ImplicitMaps;
5982  for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5983  auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5984  if (!C)
5985  continue;
5986  SmallVector<Expr *, 4> SubExprs;
5987  auto *MI = C->mapperlist_begin();
5988  for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5989  ++I, ++MI) {
5990  // Expression is mapped using mapper - skip it.
5991  if (*MI)
5992  continue;
5993  Expr *E = *I;
5994  // Expression is dependent - skip it, build the mapper when it gets
5995  // instantiated.
5996  if (E->isTypeDependent() || E->isValueDependent() ||
5998  continue;
5999  // Array section - need to check for the mapping of the array section
6000  // element.
6001  QualType CanonType = E->getType().getCanonicalType();
6002  if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
6003  const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
6004  QualType BaseType =
6006  QualType ElemType;
6007  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
6008  ElemType = ATy->getElementType();
6009  else
6010  ElemType = BaseType->getPointeeType();
6011  CanonType = ElemType;
6012  }
6013 
6014  // DFS over data members in structures/classes.
6016  1, {CanonType, nullptr});
6017  llvm::DenseMap<const Type *, Expr *> Visited;
6019  1, {nullptr, 1});
6020  while (!Types.empty()) {
6021  QualType BaseType;
6022  FieldDecl *CurFD;
6023  std::tie(BaseType, CurFD) = Types.pop_back_val();
6024  while (ParentChain.back().second == 0)
6025  ParentChain.pop_back();
6026  --ParentChain.back().second;
6027  if (BaseType.isNull())
6028  continue;
6029  // Only structs/classes are allowed to have mappers.
6030  const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6031  if (!RD)
6032  continue;
6033  auto It = Visited.find(BaseType.getTypePtr());
6034  if (It == Visited.end()) {
6035  // Try to find the associated user-defined mapper.
6036  CXXScopeSpec MapperIdScopeSpec;
6037  DeclarationNameInfo DefaultMapperId;
6038  DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6039  &S.Context.Idents.get("default")));
6040  DefaultMapperId.setLoc(E->getExprLoc());
6042  S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6043  BaseType, /*UnresolvedMapper=*/nullptr);
6044  if (ER.isInvalid())
6045  continue;
6046  It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6047  }
6048  // Found default mapper.
6049  if (It->second) {
6050  auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6051  VK_LValue, OK_Ordinary, E);
6052  OE->setIsUnique(/*V=*/true);
6053  Expr *BaseExpr = OE;
6054  for (const auto &P : ParentChain) {
6055  if (P.first) {
6056  BaseExpr = S.BuildMemberExpr(
6057  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6059  DeclAccessPair::make(P.first, P.first->getAccess()),
6060  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6061  P.first->getType(), VK_LValue, OK_Ordinary);
6062  BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6063  }
6064  }
6065  if (CurFD)
6066  BaseExpr = S.BuildMemberExpr(
6067  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6069  DeclAccessPair::make(CurFD, CurFD->getAccess()),
6070  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6071  CurFD->getType(), VK_LValue, OK_Ordinary);
6072  SubExprs.push_back(BaseExpr);
6073  continue;
6074  }
6075  // Check for the "default" mapper for data members.
6076  bool FirstIter = true;
6077  for (FieldDecl *FD : RD->fields()) {
6078  if (!FD)
6079  continue;
6080  QualType FieldTy = FD->getType();
6081  if (FieldTy.isNull() ||
6082  !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6083  continue;
6084  if (FirstIter) {
6085  FirstIter = false;
6086  ParentChain.emplace_back(CurFD, 1);
6087  } else {
6088  ++ParentChain.back().second;
6089  }
6090  Types.emplace_back(FieldTy, FD);
6091  }
6092  }
6093  }
6094  if (SubExprs.empty())
6095  continue;
6096  CXXScopeSpec MapperIdScopeSpec;
6097  DeclarationNameInfo MapperId;
6098  if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6099  nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6100  MapperIdScopeSpec, MapperId, C->getMapType(),
6101  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6102  SubExprs, OMPVarListLocTy()))
6103  Clauses.push_back(NewClause);
6104  }
6105 }
6106 
6109  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6110  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
6111  StmtResult Res = StmtError();
6113  if (const OMPBindClause *BC =
6114  OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6115  BindKind = BC->getBindKind();
6116  // First check CancelRegion which is then used in checkNestingOfRegions.
6117  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6118  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6119  BindKind, StartLoc))
6120  return StmtError();
6121 
6122  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6123  VarsWithInheritedDSAType VarsWithInheritedDSA;
6124  bool ErrorFound = false;
6125  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6126  if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6127  Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6128  Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6129  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6130 
6131  // Check default data sharing attributes for referenced variables.
6132  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6133  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6134  Stmt *S = AStmt;
6135  while (--ThisCaptureLevel >= 0)
6136  S = cast<CapturedStmt>(S)->getCapturedStmt();
6137  DSAChecker.Visit(S);
6140  // Visit subcaptures to generate implicit clauses for captured vars.
6141  auto *CS = cast<CapturedStmt>(AStmt);
6142  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6143  getOpenMPCaptureRegions(CaptureRegions, Kind);
6144  // Ignore outer tasking regions for target directives.
6145  if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6146  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6147  DSAChecker.visitSubCaptures(CS);
6148  }
6149  if (DSAChecker.isErrorFound())
6150  return StmtError();
6151  // Generate list of implicitly defined firstprivate variables.
6152  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6153 
6154  SmallVector<Expr *, 4> ImplicitFirstprivates(
6155  DSAChecker.getImplicitFirstprivate().begin(),
6156  DSAChecker.getImplicitFirstprivate().end());
6157  SmallVector<Expr *, 4> ImplicitPrivates(
6158  DSAChecker.getImplicitPrivate().begin(),
6159  DSAChecker.getImplicitPrivate().end());
6160  const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6161  SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6163  ImplicitMapModifiers[DefaultmapKindNum];
6165  ImplicitMapModifiersLoc[DefaultmapKindNum];
6166  // Get the original location of present modifier from Defaultmap clause.
6167  SourceLocation PresentModifierLocs[DefaultmapKindNum];
6168  for (OMPClause *C : Clauses) {
6169  if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6170  if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6171  PresentModifierLocs[DMC->getDefaultmapKind()] =
6172  DMC->getDefaultmapModifierLoc();
6173  }
6174  for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6175  auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6176  for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6177  ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6178  Kind, static_cast<OpenMPMapClauseKind>(I));
6179  ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6180  }
6181  ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6182  DSAChecker.getImplicitMapModifier(Kind);
6183  ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6184  ImplicitModifier.end());
6185  std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6186  ImplicitModifier.size(), PresentModifierLocs[VC]);
6187  }
6188  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6189  for (OMPClause *C : Clauses) {
6190  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6191  for (Expr *E : IRC->taskgroup_descriptors())
6192  if (E)
6193  ImplicitFirstprivates.emplace_back(E);
6194  }
6195  // OpenMP 5.0, 2.10.1 task Construct
6196  // [detach clause]... The event-handle will be considered as if it was
6197  // specified on a firstprivate clause.
6198  if (auto *DC = dyn_cast<OMPDetachClause>(C))
6199  ImplicitFirstprivates.push_back(DC->getEventHandler());
6200  }
6201  if (!ImplicitFirstprivates.empty()) {
6202  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6203  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6204  SourceLocation())) {
6205  ClausesWithImplicit.push_back(Implicit);
6206  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6207  ImplicitFirstprivates.size();
6208  } else {
6209  ErrorFound = true;
6210  }
6211  }
6212  if (!ImplicitPrivates.empty()) {
6213  if (OMPClause *Implicit =
6214  ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6216  ClausesWithImplicit.push_back(Implicit);
6217  ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6218  ImplicitPrivates.size();
6219  } else {
6220  ErrorFound = true;
6221  }
6222  }
6223  // OpenMP 5.0 [2.19.7]
6224  // If a list item appears in a reduction, lastprivate or linear
6225  // clause on a combined target construct then it is treated as
6226  // if it also appears in a map clause with a map-type of tofrom
6227  if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6229  SmallVector<Expr *, 4> ImplicitExprs;
6230  for (OMPClause *C : Clauses) {
6231  if (auto *RC = dyn_cast<OMPReductionClause>(C))
6232  for (Expr *E : RC->varlists())
6233  if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6234  ImplicitExprs.emplace_back(E);
6235  }
6236  if (!ImplicitExprs.empty()) {
6237  ArrayRef<Expr *> Exprs = ImplicitExprs;
6238  CXXScopeSpec MapperIdScopeSpec;
6239  DeclarationNameInfo MapperId;
6240  if (OMPClause *Implicit = ActOnOpenMPMapClause(
6242  MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6243  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6244  Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6245  ClausesWithImplicit.emplace_back(Implicit);
6246  }
6247  }
6248  for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6249  int ClauseKindCnt = -1;
6250  for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6251  ++ClauseKindCnt;
6252  if (ImplicitMap.empty())
6253  continue;
6254  CXXScopeSpec MapperIdScopeSpec;
6255  DeclarationNameInfo MapperId;
6256  auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6257  if (OMPClause *Implicit = ActOnOpenMPMapClause(
6258  nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6259  MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6260  SourceLocation(), SourceLocation(), ImplicitMap,
6261  OMPVarListLocTy())) {
6262  ClausesWithImplicit.emplace_back(Implicit);
6263  ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6264  ImplicitMap.size();
6265  } else {
6266  ErrorFound = true;
6267  }
6268  }
6269  }
6270  // Build expressions for implicit maps of data members with 'default'
6271  // mappers.
6272  if (LangOpts.OpenMP >= 50)
6274  ClausesWithImplicit);
6275  }
6276 
6277  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6278  switch (Kind) {
6279  case OMPD_parallel:
6280  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6281  EndLoc);
6282  AllowedNameModifiers.push_back(OMPD_parallel);
6283  break;
6284  case OMPD_simd:
6285  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6286  VarsWithInheritedDSA);
6287  if (LangOpts.OpenMP >= 50)
6288  AllowedNameModifiers.push_back(OMPD_simd);
6289  break;
6290  case OMPD_tile:
6291  Res =
6292  ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6293  break;
6294  case OMPD_unroll:
6295  Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6296  EndLoc);
6297  break;
6298  case OMPD_for:
6299  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6300  VarsWithInheritedDSA);
6301  break;
6302  case OMPD_for_simd:
6303  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6304  EndLoc, VarsWithInheritedDSA);
6305  if (LangOpts.OpenMP >= 50)
6306  AllowedNameModifiers.push_back(OMPD_simd);
6307  break;
6308  case OMPD_sections:
6309  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6310  EndLoc);
6311  break;
6312  case OMPD_section:
6313  assert(ClausesWithImplicit.empty() &&
6314  "No clauses are allowed for 'omp section' directive");
6315  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6316  break;
6317  case OMPD_single:
6318  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6319  EndLoc);
6320  break;
6321  case OMPD_master:
6322  assert(ClausesWithImplicit.empty() &&
6323  "No clauses are allowed for 'omp master' directive");
6324  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6325  break;
6326  case OMPD_masked:
6327  Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6328  EndLoc);
6329  break;
6330  case OMPD_critical:
6331  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6332  StartLoc, EndLoc);
6333  break;
6334  case OMPD_parallel_for:
6335  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6336  EndLoc, VarsWithInheritedDSA);
6337  AllowedNameModifiers.push_back(OMPD_parallel);
6338  break;
6339  case OMPD_parallel_for_simd:
6341  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6342  AllowedNameModifiers.push_back(OMPD_parallel);
6343  if (LangOpts.OpenMP >= 50)
6344  AllowedNameModifiers.push_back(OMPD_simd);
6345  break;
6346  case OMPD_parallel_master:
6347  Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6348  StartLoc, EndLoc);
6349  AllowedNameModifiers.push_back(OMPD_parallel);
6350  break;
6351  case OMPD_parallel_masked:
6352  Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6353  StartLoc, EndLoc);
6354  AllowedNameModifiers.push_back(OMPD_parallel);
6355  break;
6356  case OMPD_parallel_sections:
6357  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6358  StartLoc, EndLoc);
6359  AllowedNameModifiers.push_back(OMPD_parallel);
6360  break;
6361  case OMPD_task:
6362  Res =
6363  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6364  AllowedNameModifiers.push_back(OMPD_task);
6365  break;
6366  case OMPD_taskyield:
6367  assert(ClausesWithImplicit.empty() &&
6368  "No clauses are allowed for 'omp taskyield' directive");
6369  assert(AStmt == nullptr &&
6370  "No associated statement allowed for 'omp taskyield' directive");
6371  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6372  break;
6373  case OMPD_error:
6374  assert(AStmt == nullptr &&
6375  "No associated statement allowed for 'omp error' directive");
6376  Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6377  break;
6378  case OMPD_barrier:
6379  assert(ClausesWithImplicit.empty() &&
6380  "No clauses are allowed for 'omp barrier' directive");
6381  assert(AStmt == nullptr &&
6382  "No associated statement allowed for 'omp barrier' directive");
6383  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6384  break;
6385  case OMPD_taskwait:
6386  assert(AStmt == nullptr &&
6387  "No associated statement allowed for 'omp taskwait' directive");
6388  Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6389  break;
6390  case OMPD_taskgroup:
6391  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6392  EndLoc);
6393  break;
6394  case OMPD_flush:
6395  assert(AStmt == nullptr &&
6396  "No associated statement allowed for 'omp flush' directive");
6397  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6398  break;
6399  case OMPD_depobj:
6400  assert(AStmt == nullptr &&
6401  "No associated statement allowed for 'omp depobj' directive");
6402  Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6403  break;
6404  case OMPD_scan:
6405  assert(AStmt == nullptr &&
6406  "No associated statement allowed for 'omp scan' directive");
6407  Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6408  break;
6409  case OMPD_ordered:
6410  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6411  EndLoc);
6412  break;
6413  case OMPD_atomic:
6414  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6415  EndLoc);
6416  break;
6417  case OMPD_teams:
6418  Res =
6419  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6420  break;
6421  case OMPD_target:
6422  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6423  EndLoc);
6424  AllowedNameModifiers.push_back(OMPD_target);
6425  break;
6426  case OMPD_target_parallel:
6427  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6428  StartLoc, EndLoc);
6429  AllowedNameModifiers.push_back(OMPD_target);
6430  AllowedNameModifiers.push_back(OMPD_parallel);
6431  break;
6432  case OMPD_target_parallel_for:
6434  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6435  AllowedNameModifiers.push_back(OMPD_target);
6436  AllowedNameModifiers.push_back(OMPD_parallel);
6437  break;
6438  case OMPD_cancellation_point:
6439  assert(ClausesWithImplicit.empty() &&
6440  "No clauses are allowed for 'omp cancellation point' directive");
6441  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6442  "cancellation point' directive");
6443  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6444  break;
6445  case OMPD_cancel:
6446  assert(AStmt == nullptr &&
6447  "No associated statement allowed for 'omp cancel' directive");
6448  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6449  CancelRegion);
6450  AllowedNameModifiers.push_back(OMPD_cancel);
6451  break;
6452  case OMPD_target_data:
6453  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6454  EndLoc);
6455  AllowedNameModifiers.push_back(OMPD_target_data);
6456  break;
6457  case OMPD_target_enter_data:
6458  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6459  EndLoc, AStmt);
6460  AllowedNameModifiers.push_back(OMPD_target_enter_data);
6461  break;
6462  case OMPD_target_exit_data:
6463  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6464  EndLoc, AStmt);
6465  AllowedNameModifiers.push_back(OMPD_target_exit_data);
6466  break;
6467  case OMPD_taskloop:
6468  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6469  EndLoc, VarsWithInheritedDSA);
6470  AllowedNameModifiers.push_back(OMPD_taskloop);
6471  break;
6472  case OMPD_taskloop_simd:
6473  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6474  EndLoc, VarsWithInheritedDSA);
6475  AllowedNameModifiers.push_back(OMPD_taskloop);
6476  if (LangOpts.OpenMP >= 50)
6477  AllowedNameModifiers.push_back(OMPD_simd);
6478  break;
6479  case OMPD_master_taskloop:
6481  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6482  AllowedNameModifiers.push_back(OMPD_taskloop);
6483  break;
6484  case OMPD_masked_taskloop:
6486  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6487  AllowedNameModifiers.push_back(OMPD_taskloop);
6488  break;
6489  case OMPD_master_taskloop_simd:
6491  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6492  AllowedNameModifiers.push_back(OMPD_taskloop);
6493  if (LangOpts.OpenMP >= 50)
6494  AllowedNameModifiers.push_back(OMPD_simd);
6495  break;
6496  case OMPD_masked_taskloop_simd:
6498  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6499  if (LangOpts.OpenMP >= 51) {
6500  AllowedNameModifiers.push_back(OMPD_taskloop);
6501  AllowedNameModifiers.push_back(OMPD_simd);
6502  }
6503  break;
6504  case OMPD_parallel_master_taskloop:
6506  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6507  AllowedNameModifiers.push_back(OMPD_taskloop);
6508  AllowedNameModifiers.push_back(OMPD_parallel);
6509  break;
6510  case OMPD_parallel_masked_taskloop:
6512  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6513  if (LangOpts.OpenMP >= 51) {
6514  AllowedNameModifiers.push_back(OMPD_taskloop);
6515  AllowedNameModifiers.push_back(OMPD_parallel);
6516  }
6517  break;
6518  case OMPD_parallel_master_taskloop_simd:
6520  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6521  AllowedNameModifiers.push_back(OMPD_taskloop);
6522  AllowedNameModifiers.push_back(OMPD_parallel);
6523  if (LangOpts.OpenMP >= 50)
6524  AllowedNameModifiers.push_back(OMPD_simd);
6525  break;
6526  case OMPD_parallel_masked_taskloop_simd:
6528  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6529  if (LangOpts.OpenMP >= 51) {
6530  AllowedNameModifiers.push_back(OMPD_taskloop);
6531  AllowedNameModifiers.push_back(OMPD_parallel);
6532  AllowedNameModifiers.push_back(OMPD_simd);
6533  }
6534  break;
6535  case OMPD_distribute:
6536  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6537  EndLoc, VarsWithInheritedDSA);
6538  break;
6539  case OMPD_target_update:
6540  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6541  EndLoc, AStmt);
6542  AllowedNameModifiers.push_back(OMPD_target_update);
6543  break;
6544  case OMPD_distribute_parallel_for:
6546  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6547  AllowedNameModifiers.push_back(OMPD_parallel);
6548  break;
6549  case OMPD_distribute_parallel_for_simd:
6551  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6552  AllowedNameModifiers.push_back(OMPD_parallel);
6553  if (LangOpts.OpenMP >= 50)
6554  AllowedNameModifiers.push_back(OMPD_simd);
6555  break;
6556  case OMPD_distribute_simd:
6558  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6559  if (LangOpts.OpenMP >= 50)
6560  AllowedNameModifiers.push_back(OMPD_simd);
6561  break;
6562  case OMPD_target_parallel_for_simd:
6564  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6565  AllowedNameModifiers.push_back(OMPD_target);
6566  AllowedNameModifiers.push_back(OMPD_parallel);
6567  if (LangOpts.OpenMP >= 50)
6568  AllowedNameModifiers.push_back(OMPD_simd);
6569  break;
6570  case OMPD_target_simd:
6571  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6572  EndLoc, VarsWithInheritedDSA);
6573  AllowedNameModifiers.push_back(OMPD_target);
6574  if (LangOpts.OpenMP >= 50)
6575  AllowedNameModifiers.push_back(OMPD_simd);
6576  break;
6577  case OMPD_teams_distribute:
6579  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6580  break;
6581  case OMPD_teams_distribute_simd:
6583  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6584  if (LangOpts.OpenMP >= 50)
6585  AllowedNameModifiers.push_back(OMPD_simd);
6586  break;
6587  case OMPD_teams_distribute_parallel_for_simd:
6589  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6590  AllowedNameModifiers.push_back(OMPD_parallel);
6591  if (LangOpts.OpenMP >= 50)
6592  AllowedNameModifiers.push_back(OMPD_simd);
6593  break;
6594  case OMPD_teams_distribute_parallel_for:
6596  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6597  AllowedNameModifiers.push_back(OMPD_parallel);
6598  break;
6599  case OMPD_target_teams:
6600  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6601  EndLoc);
6602  AllowedNameModifiers.push_back(OMPD_target);
6603  break;
6604  case OMPD_target_teams_distribute:
6606  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6607  AllowedNameModifiers.push_back(OMPD_target);
6608  break;
6609  case OMPD_target_teams_distribute_parallel_for:
6611  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6612  AllowedNameModifiers.push_back(OMPD_target);
6613  AllowedNameModifiers.push_back(OMPD_parallel);
6614  break;
6615  case OMPD_target_teams_distribute_parallel_for_simd:
6617  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6618  AllowedNameModifiers.push_back(OMPD_target);
6619  AllowedNameModifiers.push_back(OMPD_parallel);
6620  if (LangOpts.OpenMP >= 50)
6621  AllowedNameModifiers.push_back(OMPD_simd);
6622  break;
6623  case OMPD_target_teams_distribute_simd:
6625  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6626  AllowedNameModifiers.push_back(OMPD_target);
6627  if (LangOpts.OpenMP >= 50)
6628  AllowedNameModifiers.push_back(OMPD_simd);
6629  break;
6630  case OMPD_interop:
6631  assert(AStmt == nullptr &&
6632  "No associated statement allowed for 'omp interop' directive");
6633  Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6634  break;
6635  case OMPD_dispatch:
6636  Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6637  EndLoc);
6638  break;
6639  case OMPD_loop:
6640  Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6641  EndLoc, VarsWithInheritedDSA);
6642  break;
6643  case OMPD_teams_loop:
6645  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6646  break;
6647  case OMPD_target_teams_loop:
6649  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6650  break;
6651  case OMPD_parallel_loop:
6653  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6654  break;
6655  case OMPD_target_parallel_loop:
6657  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6658  break;
6659  case OMPD_declare_target:
6660  case OMPD_end_declare_target:
6661  case OMPD_threadprivate:
6662  case OMPD_allocate:
6663  case OMPD_declare_reduction:
6664  case OMPD_declare_mapper:
6665  case OMPD_declare_simd:
6666  case OMPD_requires:
6667  case OMPD_declare_variant:
6668  case OMPD_begin_declare_variant:
6669  case OMPD_end_declare_variant:
6670  llvm_unreachable("OpenMP Directive is not allowed");
6671  case OMPD_unknown:
6672  default:
6673  llvm_unreachable("Unknown OpenMP directive");
6674  }
6675 
6676  ErrorFound = Res.isInvalid() || ErrorFound;
6677 
6678  // Check variables in the clauses if default(none) or
6679  // default(firstprivate) was specified.
6680  if (DSAStack->getDefaultDSA() == DSA_none ||
6681  DSAStack->getDefaultDSA() == DSA_private ||
6682  DSAStack->getDefaultDSA() == DSA_firstprivate) {
6683  DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6684  for (OMPClause *C : Clauses) {
6685  switch (C->getClauseKind()) {
6686  case OMPC_num_threads:
6687  case OMPC_dist_schedule:
6688  // Do not analyse if no parent teams directive.
6690  break;
6691  continue;
6692  case OMPC_if:
6694  cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6695  break;
6698  cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6699  break;
6700  continue;
6701  case OMPC_schedule:
6702  case OMPC_detach:
6703  break;
6704  case OMPC_grainsize:
6705  case OMPC_num_tasks:
6706  case OMPC_final:
6707  case OMPC_priority:
6708  case OMPC_novariants:
6709  case OMPC_nocontext:
6710  // Do not analyze if no parent parallel directive.
6712  break;
6713  continue;
6714  case OMPC_ordered:
6715  case OMPC_device:
6716  case OMPC_num_teams:
6717  case OMPC_thread_limit:
6718  case OMPC_hint:
6719  case OMPC_collapse:
6720  case OMPC_safelen:
6721  case OMPC_simdlen:
6722  case OMPC_sizes:
6723  case OMPC_default:
6724  case OMPC_proc_bind:
6725  case OMPC_private:
6726  case OMPC_firstprivate:
6727  case OMPC_lastprivate:
6728  case OMPC_shared:
6729  case OMPC_reduction:
6730  case OMPC_task_reduction:
6731  case OMPC_in_reduction:
6732  case OMPC_linear:
6733  case OMPC_aligned:
6734  case OMPC_copyin:
6735  case OMPC_copyprivate:
6736  case OMPC_nowait:
6737  case OMPC_untied:
6738  case OMPC_mergeable:
6739  case OMPC_allocate:
6740  case OMPC_read:
6741  case OMPC_write:
6742  case OMPC_update:
6743  case OMPC_capture:
6744  case OMPC_compare:
6745  case OMPC_seq_cst:
6746  case OMPC_acq_rel:
6747  case OMPC_acquire:
6748  case OMPC_release:
6749  case OMPC_relaxed:
6750  case OMPC_depend:
6751  case OMPC_threads:
6752  case OMPC_simd:
6753  case OMPC_map:
6754  case OMPC_nogroup:
6755  case OMPC_defaultmap:
6756  case OMPC_to:
6757  case OMPC_from:
6758  case OMPC_use_device_ptr:
6759  case OMPC_use_device_addr:
6760  case OMPC_is_device_ptr:
6761  case OMPC_has_device_addr:
6762  case OMPC_nontemporal:
6763  case OMPC_order:
6764  case OMPC_destroy:
6765  case OMPC_inclusive:
6766  case OMPC_exclusive:
6767  case OMPC_uses_allocators:
6768  case OMPC_affinity:
6769  case OMPC_bind:
6770  case OMPC_filter:
6771  continue;
6772  case OMPC_allocator:
6773  case OMPC_flush:
6774  case OMPC_depobj:
6775  case OMPC_threadprivate:
6776  case OMPC_uniform:
6777  case OMPC_unknown:
6778  case OMPC_unified_address:
6779  case OMPC_unified_shared_memory:
6780  case OMPC_reverse_offload:
6781  case OMPC_dynamic_allocators:
6782  case OMPC_atomic_default_mem_order:
6783  case OMPC_device_type:
6784  case OMPC_match:
6785  case OMPC_when:
6786  case OMPC_at:
6787  case OMPC_severity:
6788  case OMPC_message:
6789  default:
6790  llvm_unreachable("Unexpected clause");
6791  }
6792  for (Stmt *CC : C->children()) {
6793  if (CC)
6794  DSAChecker.Visit(CC);
6795  }
6796  }
6797  for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6798  VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6799  }
6800  for (const auto &P : VarsWithInheritedDSA) {
6801  if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6802  continue;
6803  ErrorFound = true;
6804  if (DSAStack->getDefaultDSA() == DSA_none ||
6805  DSAStack->getDefaultDSA() == DSA_private ||
6806  DSAStack->getDefaultDSA() == DSA_firstprivate) {
6807  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6808  << P.first << P.second->getSourceRange();
6809  Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6810  } else if (getLangOpts().OpenMP >= 50) {
6811  Diag(P.second->getExprLoc(),
6812  diag::err_omp_defaultmap_no_attr_for_variable)
6813  << P.first << P.second->getSourceRange();
6814  Diag(DSAStack->getDefaultDSALocation(),
6815  diag::note_omp_defaultmap_attr_none);
6816  }
6817  }
6818 
6819  if (!AllowedNameModifiers.empty())
6820  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6821  ErrorFound;
6822 
6823  if (ErrorFound)
6824  return StmtError();
6825 
6826  if (!CurContext->isDependentContext() &&
6828  !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6829  DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6830  DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6831  DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6832  // Register target to DSA Stack.
6833  DSAStack->addTargetDirLocation(StartLoc);
6834  }
6835 
6836  return Res;
6837 }
6838 
6840  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6841  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6842  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6843  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6844  assert(Aligneds.size() == Alignments.size());
6845  assert(Linears.size() == LinModifiers.size());
6846  assert(Linears.size() == Steps.size());
6847  if (!DG || DG.get().isNull())
6848  return DeclGroupPtrTy();
6849 
6850  const int SimdId = 0;
6851  if (!DG.get().isSingleDecl()) {
6852  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6853  << SimdId;
6854  return DG;
6855  }
6856  Decl *ADecl = DG.get().getSingleDecl();
6857  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6858  ADecl = FTD->getTemplatedDecl();
6859 
6860  auto *FD = dyn_cast<FunctionDecl>(ADecl);
6861  if (!FD) {
6862  Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6863  return DeclGroupPtrTy();
6864  }
6865 
6866  // OpenMP [2.8.2, declare simd construct, Description]
6867  // The parameter of the simdlen clause must be a constant positive integer
6868  // expression.
6869  ExprResult SL;
6870  if (Simdlen)
6871  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6872  // OpenMP [2.8.2, declare simd construct, Description]
6873  // The special this pointer can be used as if was one of the arguments to the
6874  // function in any of the linear, aligned, or uniform clauses.
6875  // The uniform clause declares one or more arguments to have an invariant
6876  // value for all concurrent invocations of the function in the execution of a
6877  // single SIMD loop.
6878  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6879  const Expr *UniformedLinearThis = nullptr;
6880  for (const Expr *E : Uniforms) {
6881  E = E->IgnoreParenImpCasts();
6882  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6883  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6884  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6885  FD->getParamDecl(PVD->getFunctionScopeIndex())
6886  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6887  UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6888  continue;
6889  }
6890  if (isa<CXXThisExpr>(E)) {
6891  UniformedLinearThis = E;
6892  continue;
6893  }
6894  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6895  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6896  }
6897  // OpenMP [2.8.2, declare simd construct, Description]
6898  // The aligned clause declares that the object to which each list item points
6899  // is aligned to the number of bytes expressed in the optional parameter of
6900  // the aligned clause.
6901  // The special this pointer can be used as if was one of the arguments to the
6902  // function in any of the linear, aligned, or uniform clauses.
6903  // The type of list items appearing in the aligned clause must be array,
6904  // pointer, reference to array, or reference to pointer.
6905  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6906  const Expr *AlignedThis = nullptr;
6907  for (const Expr *E : Aligneds) {
6908  E = E->IgnoreParenImpCasts();
6909  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6910  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6911  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6912  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6913  FD->getParamDecl(PVD->getFunctionScopeIndex())
6914  ->getCanonicalDecl() == CanonPVD) {
6915  // OpenMP [2.8.1, simd construct, Restrictions]
6916  // A list-item cannot appear in more than one aligned clause.
6917  if (AlignedArgs.count(CanonPVD) > 0) {
6918  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6919  << 1 << getOpenMPClauseName(OMPC_aligned)
6920  << E->getSourceRange();
6921  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6922  diag::note_omp_explicit_dsa)
6923  << getOpenMPClauseName(OMPC_aligned);
6924  continue;
6925  }
6926  AlignedArgs[CanonPVD] = E;
6927  QualType QTy = PVD->getType()
6928  .getNonReferenceType()
6929  .getUnqualifiedType()
6930  .getCanonicalType();
6931  const Type *Ty = QTy.getTypePtrOrNull();
6932  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6933  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6934  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6935  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6936  }
6937  continue;
6938  }
6939  }
6940  if (isa<CXXThisExpr>(E)) {
6941  if (AlignedThis) {
6942  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6943  << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6944  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6945  << getOpenMPClauseName(OMPC_aligned);
6946  }
6947  AlignedThis = E;
6948  continue;
6949  }
6950  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6951  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6952  }
6953  // The optional parameter of the aligned clause, alignment, must be a constant
6954  // positive integer expression. If no optional parameter is specified,
6955  // implementation-defined default alignments for SIMD instructions on the
6956  // target platforms are assumed.
6957  SmallVector<const Expr *, 4> NewAligns;
6958  for (Expr *E : Alignments) {
6959  ExprResult Align;
6960  if (E)
6961  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6962  NewAligns.push_back(Align.get());
6963  }
6964  // OpenMP [2.8.2, declare simd construct, Description]
6965  // The linear clause declares one or more list items to be private to a SIMD
6966  // lane and to have a linear relationship with respect to the iteration space
6967  // of a loop.
6968  // The special this pointer can be used as if was one of the arguments to the
6969  // function in any of the linear, aligned, or uniform clauses.
6970  // When a linear-step expression is specified in a linear clause it must be
6971  // either a constant integer expression or an integer-typed parameter that is
6972  // specified in a uniform clause on the directive.
6973  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6974  const bool IsUniformedThis = UniformedLinearThis != nullptr;
6975  auto MI = LinModifiers.begin();
6976  for (const Expr *E : Linears) {
6977  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6978  ++MI;
6979  E = E->IgnoreParenImpCasts();
6980  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6981  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6982  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6983  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6984  FD->getParamDecl(PVD->getFunctionScopeIndex())
6985  ->getCanonicalDecl() == CanonPVD) {
6986  // OpenMP [2.15.3.7, linear Clause, Restrictions]
6987  // A list-item cannot appear in more than one linear clause.
6988  if (LinearArgs.count(CanonPVD) > 0) {
6989  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6990  << getOpenMPClauseName(OMPC_linear)
6991  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6992  Diag(LinearArgs[CanonPVD]->getExprLoc(),
6993  diag::note_omp_explicit_dsa)
6994  << getOpenMPClauseName(OMPC_linear);
6995  continue;
6996  }
6997  // Each argument can appear in at most one uniform or linear clause.
6998  if (UniformedArgs.count(CanonPVD) > 0) {
6999  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7000  << getOpenMPClauseName(OMPC_linear)
7001  << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
7002  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7003  diag::note_omp_explicit_dsa)
7004  << getOpenMPClauseName(OMPC_uniform);
7005  continue;
7006  }
7007  LinearArgs[CanonPVD] = E;
7008  if (E->isValueDependent() || E->isTypeDependent() ||
7009  E->isInstantiationDependent() ||
7011  continue;
7012  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
7013  PVD->getOriginalType(),
7014  /*IsDeclareSimd=*/true);
7015  continue;
7016  }
7017  }
7018  if (isa<CXXThisExpr>(E)) {
7019  if (UniformedLinearThis) {
7020  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7021  << getOpenMPClauseName(OMPC_linear)
7022  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7023  << E->getSourceRange();
7024  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7025  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7026  : OMPC_linear);
7027  continue;
7028  }
7029  UniformedLinearThis = E;
7030  if (E->isValueDependent() || E->isTypeDependent() ||
7032  continue;
7033  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7034  E->getType(), /*IsDeclareSimd=*/true);
7035  continue;
7036  }
7037  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7038  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7039  }
7040  Expr *Step = nullptr;
7041  Expr *NewStep = nullptr;
7042  SmallVector<Expr *, 4> NewSteps;
7043  for (Expr *E : Steps) {
7044  // Skip the same step expression, it was checked already.
7045  if (Step == E || !E) {
7046  NewSteps.push_back(E ? NewStep : nullptr);
7047  continue;
7048  }
7049  Step = E;
7050  if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7051  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7052  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7053  if (UniformedArgs.count(CanonPVD) == 0) {
7054  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7055  << Step->getSourceRange();
7056  } else if (E->isValueDependent() || E->isTypeDependent() ||
7057  E->isInstantiationDependent() ||
7059  CanonPVD->getType()->hasIntegerRepresentation()) {
7060  NewSteps.push_back(Step);
7061  } else {
7062  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7063  << Step->getSourceRange();
7064  }
7065  continue;
7066  }
7067  NewStep = Step;
7068  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7069  !Step->isInstantiationDependent() &&
7071  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7072  .get();
7073  if (NewStep)
7074  NewStep =
7075  VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7076  }
7077  NewSteps.push_back(NewStep);
7078  }
7079  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7080  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7081  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7082  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7083  const_cast<Expr **>(Linears.data()), Linears.size(),
7084  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7085  NewSteps.data(), NewSteps.size(), SR);
7086  ADecl->addAttr(NewAttr);
7087  return DG;
7088 }
7089 
7090 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7091  QualType NewType) {
7092  assert(NewType->isFunctionProtoType() &&
7093  "Expected function type with prototype.");
7094  assert(FD->getType()->isFunctionNoProtoType() &&
7095  "Expected function with type with no prototype.");
7096  assert(FDWithProto->getType()->isFunctionProtoType() &&
7097  "Expected function with prototype.");
7098  // Synthesize parameters with the same types.
7099  FD->setType(NewType);
7101  for (const ParmVarDecl *P : FDWithProto->parameters()) {
7102  auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7103  SourceLocation(), nullptr, P->getType(),
7104  /*TInfo=*/nullptr, SC_None, nullptr);
7105  Param->setScopeInfo(0, Params.size());
7106  Param->setImplicit();
7107  Params.push_back(Param);
7108  }
7109 
7110  FD->setParams(Params);
7111 }
7112 
7114  if (D->isInvalidDecl())
7115  return;
7116  FunctionDecl *FD = nullptr;
7117  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7118  FD = UTemplDecl->getTemplatedDecl();
7119  else
7120  FD = cast<FunctionDecl>(D);
7121  assert(FD && "Expected a function declaration!");
7122 
7123  // If we are instantiating templates we do *not* apply scoped assumptions but
7124  // only global ones. We apply scoped assumption to the template definition
7125  // though.
7126  if (!inTemplateInstantiation()) {
7127  for (AssumptionAttr *AA : OMPAssumeScoped)
7128  FD->addAttr(AA);
7129  }
7130  for (AssumptionAttr *AA : OMPAssumeGlobal)
7131  FD->addAttr(AA);
7132 }
7133 
7134 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7135  : TI(&TI), NameSuffix(TI.getMangledName()) {}
7136 
7138  Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7140  if (!D.getIdentifier())
7141  return;
7142 
7143  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7144 
7145  // Template specialization is an extension, check if we do it.
7146  bool IsTemplated = !TemplateParamLists.empty();
7147  if (IsTemplated &
7148  !DVScope.TI->isExtensionActive(
7149  llvm::omp::TraitProperty::implementation_extension_allow_templates))
7150  return;
7151 
7152  IdentifierInfo *BaseII = D.getIdentifier();
7153  LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7155  LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7156 
7157  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7158  QualType FType = TInfo->getType();
7159 
7160  bool IsConstexpr =
7162  bool IsConsteval =
7164 
7165  for (auto *Candidate : Lookup) {
7166  auto *CandidateDecl = Candidate->getUnderlyingDecl();
7167  FunctionDecl *UDecl = nullptr;
7168  if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7169  auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7170  if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7171  UDecl = FTD->getTemplatedDecl();
7172  } else if (!IsTemplated)
7173  UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7174  if (!UDecl)
7175  continue;
7176 
7177  // Don't specialize constexpr/consteval functions with
7178  // non-constexpr/consteval functions.
7179  if (UDecl->isConstexpr() && !IsConstexpr)
7180  continue;
7181  if (UDecl->isConsteval() && !IsConsteval)
7182  continue;
7183 
7184  QualType UDeclTy = UDecl->getType();
7185  if (!UDeclTy->isDependentType()) {
7187  FType, UDeclTy, /* OfBlockPointer */ false,
7188  /* Unqualified */ false, /* AllowCXX */ true);
7189  if (NewType.isNull())
7190  continue;
7191  }
7192 
7193  // Found a base!
7194  Bases.push_back(UDecl);
7195  }
7196 
7197  bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7198  llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7199  // If no base was found we create a declaration that we use as base.
7200  if (Bases.empty() && UseImplicitBase) {
7202  Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7203  BaseD->setImplicit(true);
7204  if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7205  Bases.push_back(BaseTemplD->getTemplatedDecl());
7206  else
7207  Bases.push_back(cast<FunctionDecl>(BaseD));
7208  }
7209 
7210  std::string MangledName;
7211  MangledName += D.getIdentifier()->getName();
7212  MangledName += getOpenMPVariantManglingSeparatorStr();
7213  MangledName += DVScope.NameSuffix;
7214  IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7215 
7216  VariantII.setMangledOpenMPVariantName(true);
7217  D.SetIdentifier(&VariantII, D.getBeginLoc());
7218 }
7219 
7222  // Do not mark function as is used to prevent its emission if this is the
7223  // only place where it is used.
7226 
7227  FunctionDecl *FD = nullptr;
7228  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7229  FD = UTemplDecl->getTemplatedDecl();
7230  else
7231  FD = cast<FunctionDecl>(D);
7232  auto *VariantFuncRef = DeclRefExpr::Create(
7234  /* RefersToEnclosingVariableOrCapture */ false,
7235  /* NameLoc */ FD->getLocation(), FD->getType(),
7237 
7238  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7239  auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7240  Context, VariantFuncRef, DVScope.TI,
7241  /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7242  /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7243  /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7244  for (FunctionDecl *BaseFD : Bases)
7245  BaseFD->addAttr(OMPDeclareVariantA);
7246 }
7247 
7249  SourceLocation LParenLoc,
7250  MultiExprArg ArgExprs,
7251  SourceLocation RParenLoc, Expr *ExecConfig) {
7252  // The common case is a regular call we do not want to specialize at all. Try
7253  // to make that case fast by bailing early.
7254  CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7255  if (!CE)
7256  return Call;
7257 
7258  FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7259  if (!CalleeFnDecl)
7260  return Call;
7261 
7262  if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7263  CalleeFnDecl->getName().startswith_insensitive("omp_")) {
7264  // checking for any calls inside an Order region
7266  Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7267  }
7268 
7269  if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7270  return Call;
7271 
7273  std::function<void(StringRef)> DiagUnknownTrait = [this,
7274  CE](StringRef ISATrait) {
7275  // TODO Track the selector locations in a way that is accessible here to
7276  // improve the diagnostic location.
7277  Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7278  << ISATrait;
7279  };
7280  TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7281  getCurFunctionDecl(), DSAStack->getConstructTraits());
7282 
7283  QualType CalleeFnType = CalleeFnDecl->getType();
7284 
7285  SmallVector<Expr *, 4> Exprs;
7287  while (CalleeFnDecl) {
7288  for (OMPDeclareVariantAttr *A :
7289  CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7290  Expr *VariantRef = A->getVariantFuncRef();
7291 
7292  VariantMatchInfo VMI;
7293  OMPTraitInfo &TI = A->getTraitInfo();
7294  TI.getAsVariantMatchInfo(Context, VMI);
7295  if (!isVariantApplicableInContext(VMI, OMPCtx,
7296  /* DeviceSetOnly */ false))
7297  continue;
7298 
7299  VMIs.push_back(VMI);
7300  Exprs.push_back(VariantRef);
7301  }
7302 
7303  CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7304  }
7305 
7306  ExprResult NewCall;
7307  do {
7308  int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7309  if (BestIdx < 0)
7310  return Call;
7311  Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7312  Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7313 
7314  {
7315  // Try to build a (member) call expression for the current best applicable
7316  // variant expression. We allow this to fail in which case we continue
7317  // with the next best variant expression. The fail case is part of the
7318  // implementation defined behavior in the OpenMP standard when it talks
7319  // about what differences in the function prototypes: "Any differences
7320  // that the specific OpenMP context requires in the prototype of the
7321  // variant from the base function prototype are implementation defined."
7322  // This wording is there to allow the specialized variant to have a
7323  // different type than the base function. This is intended and OK but if
7324  // we cannot create a call the difference is not in the "implementation
7325  // defined range" we allow.
7326  Sema::TentativeAnalysisScope Trap(*this);
7327 
7328  if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7329  auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7330  BestExpr = MemberExpr::CreateImplicit(
7331  Context, MemberCall->getImplicitObjectArgument(),
7332  /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7333  MemberCall->getValueKind(), MemberCall->getObjectKind());
7334  }
7335  NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7336  ExecConfig);
7337  if (NewCall.isUsable()) {
7338  if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7339  FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7341  CalleeFnType, NewCalleeFnDecl->getType(),
7342  /* OfBlockPointer */ false,
7343  /* Unqualified */ false, /* AllowCXX */ true);
7344  if (!NewType.isNull())
7345  break;
7346  // Don't use the call if the function type was not compatible.
7347  NewCall = nullptr;
7348  }
7349  }
7350  }
7351 
7352  VMIs.erase(VMIs.begin() + BestIdx);
7353  Exprs.erase(Exprs.begin() + BestIdx);
7354  } while (!VMIs.empty());
7355 
7356  if (!NewCall.isUsable())
7357  return Call;
7358  return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7359 }
7360 
7361 std::optional<std::pair<FunctionDecl *, Expr *>>
7363  Expr *VariantRef, OMPTraitInfo &TI,
7364  unsigned NumAppendArgs,
7365  SourceRange SR) {
7366  if (!DG || DG.get().isNull())
7367  return std::nullopt;
7368 
7369  const int VariantId = 1;
7370  // Must be applied only to single decl.
7371  if (!DG.get().isSingleDecl()) {
7372  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7373  << VariantId << SR;
7374  return std::nullopt;
7375  }
7376  Decl *ADecl = DG.get().getSingleDecl();
7377  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7378  ADecl = FTD->getTemplatedDecl();
7379 
7380  // Decl must be a function.
7381  auto *FD = dyn_cast<FunctionDecl>(ADecl);
7382  if (!FD) {
7383  Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7384  << VariantId << SR;
7385  return std::nullopt;
7386  }
7387 
7388  auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7389  // The 'target' attribute needs to be separately checked because it does
7390  // not always signify a multiversion function declaration.
7391  return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7392  };
7393  // OpenMP is not compatible with multiversion function attributes.
7394  if (HasMultiVersionAttributes(FD)) {
7395  Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7396  << SR;
7397  return std::nullopt;
7398  }
7399 
7400  // Allow #pragma omp declare variant only if the function is not used.
7401  if (FD->isUsed(false))
7402  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7403  << FD->getLocation();
7404 
7405  // Check if the function was emitted already.
7406  const FunctionDecl *Definition;
7407  if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7408  (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7409  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7410  << FD->getLocation();
7411 
7412  // The VariantRef must point to function.
7413  if (!VariantRef) {
7414  Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7415  return std::nullopt;
7416  }
7417 
7418  auto ShouldDelayChecks = [](Expr *&E, bool) {
7419  return E && (E->isTypeDependent() || E->isValueDependent() ||
7422  };
7423  // Do not check templates, wait until instantiation.
7424  if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7425  TI.anyScoreOrCondition(ShouldDelayChecks))
7426  return std::make_pair(FD, VariantRef);
7427 
7428  // Deal with non-constant score and user condition expressions.
7429  auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7430  bool IsScore) -> bool {
7431  if (!E || E->isIntegerConstantExpr(Context))
7432  return false;
7433 
7434  if (IsScore) {
7435  // We warn on non-constant scores and pretend they were not present.
7436  Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7437  << E;
7438  E = nullptr;
7439  } else {
7440  // We could replace a non-constant user condition with "false" but we
7441  // will soon need to handle these anyway for the dynamic version of
7442  // OpenMP context selectors.
7443  Diag(E->getExprLoc(),
7444  diag::err_omp_declare_variant_user_condition_not_constant)
7445  << E;
7446  }
7447  return true;
7448  };
7449  if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7450  return std::nullopt;
7451 
7452  QualType AdjustedFnType = FD->getType();
7453  if (NumAppendArgs) {
7454  const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7455  if (!PTy) {
7456  Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7457  << SR;
7458  return std::nullopt;
7459  }
7460  // Adjust the function type to account for an extra omp_interop_t for each
7461  // specified in the append_args clause.
7462  const TypeDecl *TD = nullptr;
7463  LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7465  if (LookupName(Result, getCurScope())) {
7466  NamedDecl *ND = Result.getFoundDecl();
7467  TD = dyn_cast_or_null<TypeDecl>(ND);
7468  }
7469  if (!TD) {
7470  Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7471  return std::nullopt;
7472  }
7473  QualType InteropType = Context.getTypeDeclType(TD);
7474  if (PTy->isVariadic()) {
7475  Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7476  return std::nullopt;
7477  }
7479  Params.append(PTy->param_type_begin(), PTy->param_type_end());
7480  Params.insert(Params.end(), NumAppendArgs, InteropType);
7481  AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7482  PTy->getExtProtoInfo());
7483  }
7484 
7485  // Convert VariantRef expression to the type of the original function to
7486  // resolve possible conflicts.
7487  ExprResult VariantRefCast = VariantRef;
7488  if (LangOpts.CPlusPlus) {
7489  QualType FnPtrType;
7490  auto *Method = dyn_cast<CXXMethodDecl>(FD);
7491  if (Method && !Method->isStatic()) {
7492  const Type *ClassType =
7493  Context.getTypeDeclType(Method->getParent()).getTypePtr();
7494  FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7495  ExprResult ER;
7496  {
7497  // Build adrr_of unary op to correctly handle type checks for member
7498  // functions.
7499  Sema::TentativeAnalysisScope Trap(*this);
7500  ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7501  VariantRef);
7502  }
7503  if (!ER.isUsable()) {
7504  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7505  << VariantId << VariantRef->getSourceRange();
7506  return std::nullopt;
7507  }
7508  VariantRef = ER.get();
7509  } else {
7510  FnPtrType = Context.getPointerType(AdjustedFnType);
7511  }
7512  QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7513  if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7515  VariantRef, FnPtrType.getUnqualifiedType(),
7516  /*SuppressUserConversions=*/false, AllowedExplicit::None,
7517  /*InOverloadResolution=*/false,
7518  /*CStyle=*/false,
7519  /*AllowObjCWritebackConversion=*/false);
7520  if (ICS.isFailure()) {
7521  Diag(VariantRef->getExprLoc(),
7522  diag::err_omp_declare_variant_incompat_types)
7523  << VariantRef->getType()
7524  << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7525  << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7526  return std::nullopt;
7527  }
7528  VariantRefCast = PerformImplicitConversion(
7529  VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7530  if (!VariantRefCast.isUsable())
7531  return std::nullopt;
7532  }
7533  // Drop previously built artificial addr_of unary op for member functions.
7534  if (Method && !Method->isStatic()) {
7535  Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7536  if (auto *UO = dyn_cast<UnaryOperator>(
7537  PossibleAddrOfVariantRef->IgnoreImplicit()))
7538  VariantRefCast = UO->getSubExpr();
7539  }
7540  }
7541 
7542  ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7543  if (!ER.isUsable() ||
7544  !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7545  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7546  << VariantId << VariantRef->getSourceRange();
7547  return std::nullopt;
7548  }
7549 
7550  // The VariantRef must point to function.
7551  auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7552  if (!DRE) {
7553  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7554  << VariantId << VariantRef->getSourceRange();
7555  return std::nullopt;
7556  }
7557  auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7558  if (!NewFD) {
7559  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7560  << VariantId << VariantRef->getSourceRange();
7561  return std::nullopt;
7562  }
7563 
7564  if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7565  Diag(VariantRef->getExprLoc(),
7566  diag::err_omp_declare_variant_same_base_function)
7567  << VariantRef->getSourceRange();
7568  return std::nullopt;
7569  }
7570 
7571  // Check if function types are compatible in C.
7572  if (!LangOpts.CPlusPlus) {
7573  QualType NewType =
7574  Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7575  if (NewType.isNull()) {
7576  Diag(VariantRef->getExprLoc(),
7577  diag::err_omp_declare_variant_incompat_types)
7578  << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7579  << VariantRef->getSourceRange();
7580  return std::nullopt;
7581  }
7582  if (NewType->isFunctionProtoType()) {
7583  if (FD->getType()->isFunctionNoProtoType())
7584  setPrototype(*this, FD, NewFD, NewType);
7585  else if (NewFD->getType()->isFunctionNoProtoType())
7586  setPrototype(*this, NewFD, FD, NewType);
7587  }
7588  }
7589 
7590  // Check if variant function is not marked with declare variant directive.
7591  if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7592  Diag(VariantRef->getExprLoc(),
7593  diag::warn_omp_declare_variant_marked_as_declare_variant)
7594  << VariantRef->getSourceRange();
7595  SourceRange SR =
7596  NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7597  Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7598  return std::nullopt;
7599  }
7600 
7601  enum DoesntSupport {
7602  VirtFuncs = 1,
7603  Constructors = 3,
7604  Destructors = 4,
7605  DeletedFuncs = 5,
7606  DefaultedFuncs = 6,
7607  ConstexprFuncs = 7,
7608  ConstevalFuncs = 8,
7609  };
7610  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7611  if (CXXFD->isVirtual()) {
7612  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7613  << VirtFuncs;
7614  return std::nullopt;
7615  }
7616 
7617  if (isa<CXXConstructorDecl>(FD)) {
7618  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7619  << Constructors;
7620  return std::nullopt;
7621  }
7622 
7623  if (isa<CXXDestructorDecl>(FD)) {
7624  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7625  << Destructors;
7626  return std::nullopt;
7627  }
7628  }
7629 
7630  if (FD->isDeleted()) {
7631  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7632  << DeletedFuncs;
7633  return std::nullopt;
7634  }
7635 
7636  if (FD->isDefaulted()) {
7637  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7638  << DefaultedFuncs;
7639  return std::nullopt;
7640  }
7641 
7642  if (FD->isConstexpr()) {
7643  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7644  << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7645  return std::nullopt;
7646  }
7647 
7648  // Check general compatibility.
7650  FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7654  VariantRef->getExprLoc(),
7655  PDiag(diag::err_omp_declare_variant_doesnt_support)),
7656  PartialDiagnosticAt(VariantRef->getExprLoc(),
7657  PDiag(diag::err_omp_declare_variant_diff)
7658  << FD->getLocation()),
7659  /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7660  /*CLinkageMayDiffer=*/true))
7661  return std::nullopt;
7662  return std::make_pair(FD, cast<Expr>(DRE));
7663 }
7664 
7666  FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7667  ArrayRef<Expr *> AdjustArgsNothing,
7668  ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7669  ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7670  SourceLocation AppendArgsLoc, SourceRange SR) {
7671 
7672  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7673  // An adjust_args clause or append_args clause can only be specified if the
7674  // dispatch selector of the construct selector set appears in the match
7675  // clause.
7676 
7677  SmallVector<Expr *, 8> AllAdjustArgs;
7678  llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7679  llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7680 
7681  if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7682  VariantMatchInfo VMI;
7683  TI.getAsVariantMatchInfo(Context, VMI);
7684  if (!llvm::is_contained(
7685  VMI.ConstructTraits,
7686  llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7687  if (!AllAdjustArgs.empty())
7688  Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7689  << getOpenMPClauseName(OMPC_adjust_args);
7690  if (!AppendArgs.empty())
7691  Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7692  << getOpenMPClauseName(OMPC_append_args);
7693  return;
7694  }
7695  }
7696 
7697  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7698  // Each argument can only appear in a single adjust_args clause for each
7699  // declare variant directive.
7701 
7702  for (Expr *E : AllAdjustArgs) {
7703  E = E->IgnoreParenImpCasts();
7704  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7705  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7706  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7707  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7708  FD->getParamDecl(PVD->getFunctionScopeIndex())
7709  ->getCanonicalDecl() == CanonPVD) {
7710  // It's a parameter of the function, check duplicates.
7711  if (!AdjustVars.insert(CanonPVD).second) {
7712  Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7713  << PVD;
7714  return;
7715  }
7716  continue;
7717  }
7718  }
7719  }
7720  // Anything that is not a function parameter is an error.
7721  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7722  return;
7723  }
7724 
7725  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7726  Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7727  AdjustArgsNothing.size(),
7728  const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7729  AdjustArgsNeedDevicePtr.size(),
7730  const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7731  FD->addAttr(NewAttr);
7732 }
7733 
7735  Stmt *AStmt,
7736  SourceLocation StartLoc,
7737  SourceLocation EndLoc) {
7738  if (!AStmt)
7739  return StmtError();
7740 
7741  auto *CS = cast<CapturedStmt>(AStmt);
7742  // 1.2.2 OpenMP Language Terminology
7743  // Structured block - An executable statement with a single entry at the
7744  // top and a single exit at the bottom.
7745  // The point of exit cannot be a branch out of the structured block.
7746  // longjmp() and throw() must not violate the entry/exit criteria.
7747  CS->getCapturedDecl()->setNothrow();
7748 
7750 
7751  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7752  DSAStack->getTaskgroupReductionRef(),
7753  DSAStack->isCancelRegion());
7754 }
7755 
7756 namespace {
7757 /// Iteration space of a single for loop.
7758 struct LoopIterationSpace final {
7759  /// True if the condition operator is the strict compare operator (<, > or
7760  /// !=).
7761  bool IsStrictCompare = false;
7762  /// Condition of the loop.
7763  Expr *PreCond = nullptr;
7764  /// This expression calculates the number of iterations in the loop.
7765  /// It is always possible to calculate it before starting the loop.
7766  Expr *NumIterations = nullptr;
7767  /// The loop counter variable.
7768  Expr *CounterVar = nullptr;
7769  /// Private loop counter variable.
7770  Expr *PrivateCounterVar = nullptr;
7771  /// This is initializer for the initial value of #CounterVar.
7772  Expr *CounterInit = nullptr;
7773  /// This is step for the #CounterVar used to generate its update:
7774  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7775  Expr *CounterStep = nullptr;
7776  /// Should step be subtracted?
7777  bool Subtract = false;
7778  /// Source range of the loop init.
7779  SourceRange InitSrcRange;
7780  /// Source range of the loop condition.
7781  SourceRange CondSrcRange;
7782  /// Source range of the loop increment.
7783  SourceRange IncSrcRange;
7784  /// Minimum value that can have the loop control variable. Used to support
7785  /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7786  /// since only such variables can be used in non-loop invariant expressions.
7787  Expr *MinValue = nullptr;
7788  /// Maximum value that can have the loop control variable. Used to support
7789  /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7790  /// since only such variables can be used in non-loop invariant expressions.
7791  Expr *MaxValue = nullptr;
7792  /// true, if the lower bound depends on the outer loop control var.
7793  bool IsNonRectangularLB = false;
7794  /// true, if the upper bound depends on the outer loop control var.
7795  bool IsNonRectangularUB = false;
7796  /// Index of the loop this loop depends on and forms non-rectangular loop
7797  /// nest.
7798  unsigned LoopDependentIdx = 0;
7799  /// Final condition for the non-rectangular loop nest support. It is used to
7800  /// check that the number of iterations for this particular counter must be
7801  /// finished.
7802  Expr *FinalCondition = nullptr;
7803 };
7804 
7805 /// Helper class for checking canonical form of the OpenMP loops and
7806 /// extracting iteration space of each loop in the loop nest, that will be used
7807 /// for IR generation.
7808 class OpenMPIterationSpaceChecker {
7809  /// Reference to Sema.
7810  Sema &SemaRef;
7811  /// Does the loop associated directive support non-rectangular loops?
7812  bool SupportsNonRectangular;
7813  /// Data-sharing stack.
7814  DSAStackTy &Stack;
7815  /// A location for diagnostics (when there is no some better location).
7816  SourceLocation DefaultLoc;
7817  /// A location for diagnostics (when increment is not compatible).
7818  SourceLocation ConditionLoc;
7819  /// A source location for referring to loop init later.
7820  SourceRange InitSrcRange;
7821  /// A source location for referring to condition later.
7822  SourceRange ConditionSrcRange;
7823  /// A source location for referring to increment later.
7824  SourceRange IncrementSrcRange;
7825  /// Loop variable.
7826  ValueDecl *LCDecl = nullptr;
7827  /// Reference to loop variable.
7828  Expr *LCRef = nullptr;
7829  /// Lower bound (initializer for the var).
7830  Expr *LB = nullptr;
7831  /// Upper bound.
7832  Expr *UB = nullptr;
7833  /// Loop step (increment).
7834  Expr *Step = nullptr;
7835  /// This flag is true when condition is one of:
7836  /// Var < UB
7837  /// Var <= UB
7838  /// UB > Var
7839  /// UB >= Var
7840  /// This will have no value when the condition is !=
7841  std::optional<bool> TestIsLessOp;
7842  /// This flag is true when condition is strict ( < or > ).
7843  bool TestIsStrictOp = false;
7844  /// This flag is true when step is subtracted on each iteration.
7845  bool SubtractStep = false;
7846  /// The outer loop counter this loop depends on (if any).
7847  const ValueDecl *DepDecl = nullptr;
7848  /// Contains number of loop (starts from 1) on which loop counter init
7849  /// expression of this loop depends on.
7850  std::optional<unsigned> InitDependOnLC;
7851  /// Contains number of loop (starts from 1) on which loop counter condition
7852  /// expression of this loop depends on.
7853  std::optional<unsigned> CondDependOnLC;
7854  /// Checks if the provide statement depends on the loop counter.
7855  std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
7856  bool IsInitializer);
7857  /// Original condition required for checking of the exit condition for
7858  /// non-rectangular loop.
7859  Expr *Condition = nullptr;
7860 
7861 public:
7862  OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7863  DSAStackTy &Stack, SourceLocation DefaultLoc)
7864  : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7865  Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7866  /// Check init-expr for canonical loop form and save loop counter
7867  /// variable - #Var and its initialization value - #LB.
7868  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7869  /// Check test-expr for canonical form, save upper-bound (#UB), flags
7870  /// for less/greater and for strict/non-strict comparison.
7871  bool checkAndSetCond(Expr *S);
7872  /// Check incr-expr for canonical loop form and return true if it
7873  /// does not conform, otherwise save loop step (#Step).
7874  bool checkAndSetInc(Expr *S);
7875  /// Return the loop counter variable.
7876  ValueDecl *getLoopDecl() const { return LCDecl; }
7877  /// Return the reference expression to loop counter variable.
7878  Expr *getLoopDeclRefExpr() const { return LCRef; }
7879  /// Source range of the loop init.
7880  SourceRange getInitSrcRange() const { return InitSrcRange; }
7881  /// Source range of the loop condition.
7882  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7883  /// Source range of the loop increment.
7884  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7885  /// True if the step should be subtracted.
7886  bool shouldSubtractStep() const { return SubtractStep; }
7887  /// True, if the compare operator is strict (<, > or !=).
7888  bool isStrictTestOp() const { return TestIsStrictOp; }
7889  /// Build the expression to calculate the number of iterations.
7890  Expr *buildNumIterations(
7891  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7892  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7893  /// Build the precondition expression for the loops.
7894  Expr *
7895  buildPreCond(Scope *S, Expr *Cond,
7896  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7897  /// Build reference expression to the counter be used for codegen.
7898  DeclRefExpr *
7899  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7900  DSAStackTy &DSA) const;
7901  /// Build reference expression to the private counter be used for
7902  /// codegen.
7903  Expr *buildPrivateCounterVar() const;
7904  /// Build initialization of the counter be used for codegen.
7905  Expr *buildCounterInit() const;
7906  /// Build step of the counter be used for codegen.
7907  Expr *buildCounterStep() const;
7908  /// Build loop data with counter value for depend clauses in ordered
7909  /// directives.
7910  Expr *
7911  buildOrderedLoopData(Scope *S, Expr *Counter,
7912  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7913  SourceLocation Loc, Expr *Inc = nullptr,
7914  OverloadedOperatorKind OOK = OO_Amp);
7915  /// Builds the minimum value for the loop counter.
7916  std::pair<Expr *, Expr *> buildMinMaxValues(
7917  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7918  /// Builds final condition for the non-rectangular loops.
7919  Expr *buildFinalCondition(Scope *S) const;
7920  /// Return true if any expression is dependent.
7921  bool dependent() const;
7922  /// Returns true if the initializer forms non-rectangular loop.
7923  bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
7924  /// Returns true if the condition forms non-rectangular loop.
7925  bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
7926  /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7927  unsigned getLoopDependentIdx() const {
7928  return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7929  }
7930 
7931 private:
7932  /// Check the right-hand side of an assignment in the increment
7933  /// expression.
7934  bool checkAndSetIncRHS(Expr *RHS);
7935  /// Helper to set loop counter variable and its initializer.
7936  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7937  bool EmitDiags);
7938  /// Helper to set upper bound.
7939  bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
7940  SourceRange SR, SourceLocation SL);
7941  /// Helper to set loop increment.
7942  bool setStep(Expr *NewStep, bool Subtract);
7943 };
7944 
7945 bool OpenMPIterationSpaceChecker::dependent() const {
7946  if (!LCDecl) {
7947  assert(!LB && !UB && !Step);
7948  return false;
7949  }
7950  return LCDecl->getType()->isDependentType() ||
7951  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7952  (Step && Step->isValueDependent());
7953 }
7954 
7955 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7956  Expr *NewLCRefExpr,
7957  Expr *NewLB, bool EmitDiags) {
7958  // State consistency checking to ensure correct usage.
7959  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7960  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7961  if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7962  return true;
7963  LCDecl = getCanonicalDecl(NewLCDecl);
7964  LCRef = NewLCRefExpr;
7965  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7966  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7967  if ((Ctor->isCopyOrMoveConstructor() ||
7968  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7969  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7970  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7971  LB = NewLB;
7972  if (EmitDiags)
7973  InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7974  return false;
7975 }
7976 
7977 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
7978  bool StrictOp, SourceRange SR,
7979  SourceLocation SL) {
7980  // State consistency checking to ensure correct usage.
7981  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7982  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7983  if (!NewUB || NewUB->containsErrors())
7984  return true;
7985  UB = NewUB;
7986  if (LessOp)
7987  TestIsLessOp = LessOp;
7988  TestIsStrictOp = StrictOp;
7989  ConditionSrcRange = SR;
7990  ConditionLoc = SL;
7991  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7992  return false;
7993 }
7994 
7995 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7996  // State consistency checking to ensure correct usage.
7997  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7998  if (!NewStep || NewStep->containsErrors())
7999  return true;
8000  if (!NewStep->isValueDependent()) {
8001  // Check that the step is integer expression.
8002  SourceLocation StepLoc = NewStep->getBeginLoc();
8004  StepLoc, getExprAsWritten(NewStep));
8005  if (Val.isInvalid())
8006  return true;
8007  NewStep = Val.get();
8008 
8009  // OpenMP [2.6, Canonical Loop Form, Restrictions]
8010  // If test-expr is of form var relational-op b and relational-op is < or
8011  // <= then incr-expr must cause var to increase on each iteration of the
8012  // loop. If test-expr is of form var relational-op b and relational-op is
8013  // > or >= then incr-expr must cause var to decrease on each iteration of
8014  // the loop.
8015  // If test-expr is of form b relational-op var and relational-op is < or
8016  // <= then incr-expr must cause var to decrease on each iteration of the
8017  // loop. If test-expr is of form b relational-op var and relational-op is
8018  // > or >= then incr-expr must cause var to increase on each iteration of
8019  // the loop.
8020  std::optional<llvm::APSInt> Result =
8021  NewStep->getIntegerConstantExpr(SemaRef.Context);
8022  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8023  bool IsConstNeg =
8024  Result && Result->isSigned() && (Subtract != Result->isNegative());
8025  bool IsConstPos =
8026  Result && Result->isSigned() && (Subtract == Result->isNegative());
8027  bool IsConstZero = Result && !Result->getBoolValue();
8028 
8029  // != with increment is treated as <; != with decrement is treated as >
8030  if (!TestIsLessOp)
8031  TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8032  if (UB && (IsConstZero ||
8033  (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8034  : (IsConstPos || (IsUnsigned && !Subtract))))) {
8035  SemaRef.Diag(NewStep->getExprLoc(),
8036  diag::err_omp_loop_incr_not_compatible)
8037  << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8038  SemaRef.Diag(ConditionLoc,
8039  diag::note_omp_loop_cond_requres_compatible_incr)
8040  << *TestIsLessOp << ConditionSrcRange;
8041  return true;
8042  }
8043  if (*TestIsLessOp == Subtract) {
8044  NewStep =
8045  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8046  .get();
8047  Subtract = !Subtract;
8048  }
8049  }
8050 
8051  Step = NewStep;
8052  SubtractStep = Subtract;
8053  return false;
8054 }
8055 
8056 namespace {
8057 /// Checker for the non-rectangular loops. Checks if the initializer or
8058 /// condition expression references loop counter variable.
8059 class LoopCounterRefChecker final
8060  : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8061  Sema &SemaRef;
8062  DSAStackTy &Stack;
8063  const ValueDecl *CurLCDecl = nullptr;
8064  const ValueDecl *DepDecl = nullptr;
8065  const ValueDecl *PrevDepDecl = nullptr;
8066  bool IsInitializer = true;
8067  bool SupportsNonRectangular;
8068  unsigned BaseLoopId = 0;
8069  bool checkDecl(const Expr *E, const ValueDecl *VD) {
8070  if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8071  SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8072  << (IsInitializer ? 0 : 1);
8073  return false;
8074  }
8075  const auto &&Data = Stack.isLoopControlVariable(VD);
8076  // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8077  // The type of the loop iterator on which we depend may not have a random
8078  // access iterator type.
8079  if (Data.first && VD->getType()->isRecordType()) {
8080  SmallString<128> Name;
8081  llvm::raw_svector_ostream OS(Name);
8082  VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8083  /*Qualified=*/true);
8084  SemaRef.Diag(E->getExprLoc(),
8085  diag::err_omp_wrong_dependency_iterator_type)
8086  << OS.str();
8087  SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8088  return false;
8089  }
8090  if (Data.first && !SupportsNonRectangular) {
8091  SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8092  return false;
8093  }
8094  if (Data.first &&
8095  (DepDecl || (PrevDepDecl &&
8096  getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8097  if (!DepDecl && PrevDepDecl)
8098  DepDecl = PrevDepDecl;
8099  SmallString<128> Name;
8100  llvm::raw_svector_ostream OS(Name);
8101  DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8102  /*Qualified=*/true);
8103  SemaRef.Diag(E->getExprLoc(),
8104  diag::err_omp_invariant_or_linear_dependency)
8105  << OS.str();
8106  return false;
8107  }
8108  if (Data.first) {
8109  DepDecl = VD;
8110  BaseLoopId = Data.first;
8111  }
8112  return Data.first;
8113  }
8114 
8115 public:
8116  bool VisitDeclRefExpr(const DeclRefExpr *E) {
8117  const ValueDecl *VD = E->getDecl();
8118  if (isa<VarDecl>(VD))
8119  return checkDecl(E, VD);
8120  return false;
8121  }
8122  bool VisitMemberExpr(const MemberExpr *E) {
8123  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8124  const ValueDecl *VD = E->getMemberDecl();
8125  if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8126  return checkDecl(E, VD);
8127  }
8128  return false;
8129  }
8130  bool VisitStmt(const Stmt *S) {
8131  bool Res = false;
8132  for (const Stmt *Child : S->children())
8133  Res = (Child && Visit(Child)) || Res;
8134  return Res;
8135  }
8136  explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8137  const ValueDecl *CurLCDecl, bool IsInitializer,
8138  const ValueDecl *PrevDepDecl = nullptr,
8139  bool SupportsNonRectangular = true)
8140  : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8141  PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8142  SupportsNonRectangular(SupportsNonRectangular) {}
8143  unsigned getBaseLoopId() const {
8144  assert(CurLCDecl && "Expected loop dependency.");
8145  return BaseLoopId;
8146  }
8147  const ValueDecl *getDepDecl() const {
8148  assert(CurLCDecl && "Expected loop dependency.");
8149  return DepDecl;
8150  }
8151 };
8152 } // namespace
8153 
8154 std::optional<unsigned>
8155 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8156  bool IsInitializer) {
8157  // Check for the non-rectangular loops.
8158  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8159  DepDecl, SupportsNonRectangular);
8160  if (LoopStmtChecker.Visit(S)) {
8161  DepDecl = LoopStmtChecker.getDepDecl();
8162  return LoopStmtChecker.getBaseLoopId();
8163  }
8164  return std::nullopt;
8165 }
8166 
8167 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8168  // Check init-expr for canonical loop form and save loop counter
8169  // variable - #Var and its initialization value - #LB.
8170  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8171  // var = lb
8172  // integer-type var = lb
8173  // random-access-iterator-type var = lb
8174  // pointer-type var = lb
8175  //
8176  if (!S) {
8177  if (EmitDiags) {
8178  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8179  }
8180  return true;
8181  }
8182  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8183  if (!ExprTemp->cleanupsHaveSideEffects())
8184  S = ExprTemp->getSubExpr();
8185 
8186  InitSrcRange = S->getSourceRange();
8187  if (Expr *E = dyn_cast<Expr>(S))
8188  S = E->IgnoreParens();
8189  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8190  if (BO->getOpcode() == BO_Assign) {
8191  Expr *LHS = BO->getLHS()->IgnoreParens();
8192  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8193  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8194  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8195  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8196  EmitDiags);
8197  return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8198  }
8199  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8200  if (ME->isArrow() &&
8201  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8202  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8203  EmitDiags);
8204  }
8205  }
8206  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8207  if (DS->isSingleDecl()) {
8208  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8209  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8210  // Accept non-canonical init form here but emit ext. warning.
8211  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8212  SemaRef.Diag(S->getBeginLoc(),
8213  diag::ext_omp_loop_not_canonical_init)
8214  << S->getSourceRange();
8215  return setLCDeclAndLB(
8216  Var,
8217  buildDeclRefExpr(SemaRef, Var,
8218  Var->getType().getNonReferenceType(),
8219  DS->getBeginLoc()),
8220  Var->getInit(), EmitDiags);
8221  }
8222  }
8223  }
8224  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8225  if (CE->getOperator() == OO_Equal) {
8226  Expr *LHS = CE->getArg(0);
8227  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8228  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8229  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8230  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8231  EmitDiags);
8232  return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8233  }
8234  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8235  if (ME->isArrow() &&
8236  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8237  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8238  EmitDiags);
8239  }
8240  }
8241  }
8242 
8243  if (dependent() || SemaRef.CurContext->isDependentContext())
8244  return false;
8245  if (EmitDiags) {
8246  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8247  << S->getSourceRange();
8248  }
8249  return true;
8250 }
8251 
8252 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8253 /// variable (which may be the loop variable) if possible.
8254 static const ValueDecl *getInitLCDecl(const Expr *E) {
8255  if (!E)
8256  return nullptr;
8257  E = getExprAsWritten(E);
8258  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8259  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8260  if ((Ctor->isCopyOrMoveConstructor() ||
8261  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8262  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8263  E = CE->getArg(0)->IgnoreParenImpCasts();
8264  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8265  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8266  return getCanonicalDecl(VD);
8267  }
8268  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8269  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8270  return getCanonicalDecl(ME->getMemberDecl());
8271  return nullptr;
8272 }
8273 
8274 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8275  // Check test-expr for canonical form, save upper-bound UB, flags for
8276  // less/greater and for strict/non-strict comparison.
8277  // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8278  // var relational-op b
8279  // b relational-op var
8280  //
8281  bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8282  if (!S) {
8283  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8284  << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8285  return true;
8286  }
8287  Condition = S;
8288  S = getExprAsWritten(S);
8289  SourceLocation CondLoc = S->getBeginLoc();
8290  auto &&CheckAndSetCond =
8291  [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8292  const Expr *RHS, SourceRange SR,
8293  SourceLocation OpLoc) -> std::optional<bool> {
8295  if (getInitLCDecl(LHS) == LCDecl)
8296  return setUB(const_cast<Expr *>(RHS),
8297  (Opcode == BO_LT || Opcode == BO_LE),
8298  (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8299  if (getInitLCDecl(RHS) == LCDecl)
8300  return setUB(const_cast<Expr *>(LHS),
8301  (Opcode == BO_GT || Opcode == BO_GE),
8302  (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8303  } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8304  return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8305  /*LessOp=*/std::nullopt,
8306  /*StrictOp=*/true, SR, OpLoc);
8307  }
8308  return std::nullopt;
8309  };
8310  std::optional<bool> Res;
8311  if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8312  CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8313  Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8314  RBO->getOperatorLoc());
8315  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8316  Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8317  BO->getSourceRange(), BO->getOperatorLoc());
8318  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8319  if (CE->getNumArgs() == 2) {
8320  Res = CheckAndSetCond(
8321  BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8322  CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8323  }
8324  }
8325  if (Res)
8326  return *Res;
8327  if (dependent() || SemaRef.CurContext->isDependentContext())
8328  return false;
8329  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8330  << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8331  return true;
8332 }
8333 
8334 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8335  // RHS of canonical loop form increment can be:
8336  // var + incr
8337  // incr + var
8338  // var - incr
8339  //
8340  RHS = RHS->IgnoreParenImpCasts();
8341  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8342  if (BO->isAdditiveOp()) {
8343  bool IsAdd = BO->getOpcode() == BO_Add;
8344  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8345  return setStep(BO->getRHS(), !IsAdd);
8346  if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8347  return setStep(BO->getLHS(), /*Subtract=*/false);
8348  }
8349  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8350  bool IsAdd = CE->getOperator() == OO_Plus;
8351  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8352  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8353  return setStep(CE->getArg(1), !IsAdd);
8354  if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8355  return setStep(CE->getArg(0), /*Subtract=*/false);
8356  }
8357  }
8358  if (dependent() || SemaRef.CurContext->isDependentContext())
8359  return false;
8360  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8361  << RHS->getSourceRange() << LCDecl;
8362  return true;
8363 }
8364 
8365 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8366  // Check incr-expr for canonical loop form and return true if it
8367  // does not conform.
8368  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8369  // ++var
8370  // var++
8371  // --var
8372  // var--
8373  // var += incr
8374  // var -= incr
8375  // var = var + incr
8376  // var = incr + var
8377  // var = var - incr
8378  //
8379  if (!S) {
8380  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8381  return true;
8382  }
8383  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8384  if (!ExprTemp->cleanupsHaveSideEffects())
8385  S = ExprTemp->getSubExpr();
8386 
8387  IncrementSrcRange = S->getSourceRange();
8388  S = S->IgnoreParens();
8389  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8390  if (UO->isIncrementDecrementOp() &&
8391  getInitLCDecl(UO->getSubExpr()) == LCDecl)
8392  return setStep(SemaRef
8393  .ActOnIntegerConstant(UO->getBeginLoc(),
8394  (UO->isDecrementOp() ? -1 : 1))
8395  .get(),
8396  /*Subtract=*/false);
8397  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8398  switch (BO->getOpcode()) {
8399  case BO_AddAssign:
8400  case BO_SubAssign:
8401  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8402  return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8403  break;
8404  case BO_Assign:
8405  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8406  return checkAndSetIncRHS(BO->getRHS());
8407  break;
8408  default:
8409  break;
8410  }
8411  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8412  switch (CE->getOperator()) {
8413  case OO_PlusPlus:
8414  case OO_MinusMinus:
8415  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8416  return setStep(SemaRef
8417  .ActOnIntegerConstant(
8418  CE->getBeginLoc(),
8419  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8420  .get(),
8421  /*Subtract=*/false);
8422  break;
8423  case OO_PlusEqual:
8424  case OO_MinusEqual:
8425  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8426  return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8427  break;
8428  case OO_Equal:
8429  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8430  return checkAndSetIncRHS(CE->getArg(1));
8431  break;
8432  default:
8433  break;
8434  }
8435  }
8436  if (dependent() || SemaRef.CurContext->isDependentContext())
8437  return false;
8438  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8439  << S->getSourceRange() << LCDecl;
8440  return true;
8441 }
8442 
8443 static ExprResult
8444 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8445  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8446  StringRef Name = ".capture_expr.") {
8447  if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8448  return Capture;
8449  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8450  return SemaRef.PerformImplicitConversion(
8451  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8452  /*AllowExplicit=*/true);
8453  auto I = Captures.find(Capture);
8454  if (I != Captures.end())
8455  return buildCapture(SemaRef, Capture, I->second, Name);
8456  DeclRefExpr *Ref = nullptr;
8457  ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8458  Captures[Capture] = Ref;
8459  return Res;
8460 }
8461 
8462 /// Calculate number of iterations, transforming to unsigned, if number of
8463 /// iterations may be larger than the original type.
8464 static Expr *
8465 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8466  Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8467  bool TestIsStrictOp, bool RoundToStep,
8468  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8469  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8470  if (!NewStep.isUsable())
8471  return nullptr;
8472  llvm::APSInt LRes, SRes;
8473  bool IsLowerConst = false, IsStepConst = false;
8474  if (std::optional<llvm::APSInt> Res =
8475  Lower->getIntegerConstantExpr(SemaRef.Context)) {
8476  LRes = *Res;
8477  IsLowerConst = true;
8478  }
8479  if (std::optional<llvm::APSInt> Res =
8480  Step->getIntegerConstantExpr(SemaRef.Context)) {
8481  SRes = *Res;
8482  IsStepConst = true;
8483  }
8484  bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8485  ((!TestIsStrictOp && LRes.isNonNegative()) ||
8486  (TestIsStrictOp && LRes.isStrictlyPositive()));
8487  bool NeedToReorganize = false;
8488  // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8489  if (!NoNeedToConvert && IsLowerConst &&
8490  (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8491  NoNeedToConvert = true;
8492  if (RoundToStep) {
8493  unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8494  ? LRes.getBitWidth()
8495  : SRes.getBitWidth();
8496  LRes = LRes.extend(BW + 1);
8497  LRes.setIsSigned(true);
8498  SRes = SRes.extend(BW + 1);
8499  SRes.setIsSigned(true);
8500  LRes -= SRes;
8501  NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8502  LRes = LRes.trunc(BW);
8503  }
8504  if (TestIsStrictOp) {
8505  unsigned BW = LRes.getBitWidth();
8506  LRes = LRes.extend(BW + 1);
8507  LRes.setIsSigned(true);
8508  ++LRes;
8509  NoNeedToConvert =
8510  NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8511  // truncate to the original bitwidth.
8512  LRes = LRes.trunc(BW);
8513  }
8514  NeedToReorganize = NoNeedToConvert;
8515  }
8516  llvm::APSInt URes;
8517  bool IsUpperConst = false;
8518  if (std::optional<llvm::APSInt> Res =
8519  Upper->getIntegerConstantExpr(SemaRef.Context)) {
8520  URes = *Res;
8521  IsUpperConst = true;
8522  }
8523  if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8524  (!RoundToStep || IsStepConst)) {
8525  unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8526  : URes.getBitWidth();
8527  LRes = LRes.extend(BW + 1);
8528  LRes.setIsSigned(true);
8529  URes = URes.extend(BW + 1);
8530  URes.setIsSigned(true);
8531  URes -= LRes;
8532  NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8533  NeedToReorganize = NoNeedToConvert;
8534  }
8535  // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8536  // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8537  // unsigned.
8538  if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8539  !LCTy->isDependentType() && LCTy->isIntegerType()) {
8540  QualType LowerTy = Lower->getType();
8541  QualType UpperTy = Upper->getType();
8542  uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8543  uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8544  if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8545  (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8547  LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8548  Upper =
8549  SemaRef
8551  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8553  .get();
8554  Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8555  NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8556  }
8557  }
8558  if (!Lower || !Upper || NewStep.isInvalid())
8559  return nullptr;
8560 
8561  ExprResult Diff;
8562  // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8563  // 1]).
8564  if (NeedToReorganize) {
8565  Diff = Lower;
8566 
8567  if (RoundToStep) {
8568  // Lower - Step
8569  Diff =
8570  SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8571  if (!Diff.isUsable())
8572  return nullptr;
8573  }
8574 
8575  // Lower - Step [+ 1]
8576  if (TestIsStrictOp)
8577  Diff = SemaRef.BuildBinOp(
8578  S, DefaultLoc, BO_Add, Diff.get(),
8579  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8580  if (!Diff.isUsable())
8581  return nullptr;
8582 
8583  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8584  if (!Diff.isUsable())
8585  return nullptr;
8586 
8587  // Upper - (Lower - Step [+ 1]).
8588  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8589  if (!Diff.isUsable())
8590  return nullptr;
8591  } else {
8592  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8593 
8594  if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8595  // BuildBinOp already emitted error, this one is to point user to upper
8596  // and lower bound, and to tell what is passed to 'operator-'.
8597  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8598  << Upper->getSourceRange() << Lower->getSourceRange();
8599  return nullptr;
8600  }
8601 
8602  if (!Diff.isUsable())
8603  return nullptr;
8604 
8605  // Upper - Lower [- 1]
8606  if (TestIsStrictOp)
8607  Diff = SemaRef.BuildBinOp(
8608  S, DefaultLoc, BO_Sub, Diff.get(),
8609  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8610  if (!Diff.isUsable())
8611  return nullptr;
8612 
8613  if (RoundToStep) {
8614  // Upper - Lower [- 1] + Step
8615  Diff =
8616  SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8617  if (!Diff.isUsable())
8618  return nullptr;
8619  }
8620  }
8621 
8622  // Parentheses (for dumping/debugging purposes only).
8623  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8624  if (!Diff.isUsable())
8625  return nullptr;
8626 
8627  // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8628  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8629  if (!Diff.isUsable())
8630  return nullptr;
8631 
8632  return Diff.get();
8633 }
8634 
8635 /// Build the expression to calculate the number of iterations.
8636 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8637  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8638  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8639  QualType VarType = LCDecl->getType().getNonReferenceType();
8640  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8641  !SemaRef.getLangOpts().CPlusPlus)
8642  return nullptr;
8643  Expr *LBVal = LB;
8644  Expr *UBVal = UB;
8645  // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8646  // max(LB(MinVal), LB(MaxVal)))
8647  if (InitDependOnLC) {
8648  const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8649  if (!IS.MinValue || !IS.MaxValue)
8650  return nullptr;
8651  // OuterVar = Min
8652  ExprResult MinValue =
8653  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8654  if (!MinValue.isUsable())
8655  return nullptr;
8656 
8657  ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8658  IS.CounterVar, MinValue.get());
8659  if (!LBMinVal.isUsable())
8660  return nullptr;
8661  // OuterVar = Min, LBVal
8662  LBMinVal =
8663  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8664  if (!LBMinVal.isUsable())
8665  return nullptr;
8666  // (OuterVar = Min, LBVal)
8667  LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8668  if (!LBMinVal.isUsable())
8669  return nullptr;
8670 
8671  // OuterVar = Max
8672  ExprResult MaxValue =
8673  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8674  if (!MaxValue.isUsable())
8675  return nullptr;
8676 
8677  ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8678  IS.CounterVar, MaxValue.get());
8679  if (!LBMaxVal.isUsable())
8680  return nullptr;
8681  // OuterVar = Max, LBVal
8682  LBMaxVal =
8683  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8684  if (!LBMaxVal.isUsable())
8685  return nullptr;
8686  // (OuterVar = Max, LBVal)
8687  LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8688  if (!LBMaxVal.isUsable())
8689  return nullptr;
8690 
8691  Expr *LBMin =
8692  tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8693  Expr *LBMax =
8694  tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8695  if (!LBMin || !LBMax)
8696  return nullptr;
8697  // LB(MinVal) < LB(MaxVal)
8698  ExprResult MinLessMaxRes =
8699  SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8700  if (!MinLessMaxRes.isUsable())
8701  return nullptr;
8702  Expr *MinLessMax =
8703  tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8704  .get();
8705  if (!MinLessMax)
8706  return nullptr;
8707  if (*TestIsLessOp) {
8708  // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8709  // LB(MaxVal))
8710  ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8711  MinLessMax, LBMin, LBMax);
8712  if (!MinLB.isUsable())
8713  return nullptr;
8714  LBVal = MinLB.get();
8715  } else {
8716  // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8717  // LB(MaxVal))
8718  ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8719  MinLessMax, LBMax, LBMin);
8720  if (!MaxLB.isUsable())
8721  return nullptr;
8722  LBVal = MaxLB.get();
8723  }
8724  // OuterVar = LB
8725  LBMinVal =
8726  SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8727  if (!LBMinVal.isUsable())
8728  return nullptr;
8729  LBVal = LBMinVal.get();
8730  }
8731  // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8732  // min(UB(MinVal), UB(MaxVal))
8733  if (CondDependOnLC) {
8734  const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8735  if (!IS.MinValue || !IS.MaxValue)
8736  return nullptr;
8737  // OuterVar = Min
8738  ExprResult MinValue =
8739  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8740  if (!MinValue.isUsable())
8741  return nullptr;
8742 
8743  ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8744  IS.CounterVar, MinValue.get());
8745  if (!UBMinVal.isUsable())
8746  return nullptr;
8747  // OuterVar = Min, UBVal
8748  UBMinVal =
8749  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8750  if (!UBMinVal.isUsable())
8751  return nullptr;
8752  // (OuterVar = Min, UBVal)
8753  UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8754  if (!UBMinVal.isUsable())
8755  return nullptr;
8756 
8757  // OuterVar = Max
8758  ExprResult MaxValue =
8759  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8760  if (!MaxValue.isUsable())
8761  return nullptr;
8762 
8763  ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8764  IS.CounterVar, MaxValue.get());
8765  if (!UBMaxVal.isUsable())
8766  return nullptr;
8767  // OuterVar = Max, UBVal
8768  UBMaxVal =
8769  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8770  if (!UBMaxVal.isUsable())
8771  return nullptr;
8772  // (OuterVar = Max, UBVal)
8773  UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8774  if (!UBMaxVal.isUsable())
8775  return nullptr;
8776 
8777  Expr *UBMin =
8778  tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8779  Expr *UBMax =
8780  tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8781  if (!UBMin || !UBMax)
8782  return nullptr;
8783  // UB(MinVal) > UB(MaxVal)
8784  ExprResult MinGreaterMaxRes =
8785  SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8786  if (!MinGreaterMaxRes.isUsable())
8787  return nullptr;
8788  Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8789  Captures, ".min_greater_max")
8790  .get();
8791  if (!MinGreaterMax)
8792  return nullptr;
8793  if (*TestIsLessOp) {
8794  // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8795  // UB(MaxVal))
8796  ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8797  DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8798  if (!MaxUB.isUsable())
8799  return nullptr;
8800  UBVal = MaxUB.get();
8801  } else {
8802  // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8803  // UB(MaxVal))
8804  ExprResult MinUB = SemaRef.ActOnConditionalOp(
8805  DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8806  if (!MinUB.isUsable())
8807  return nullptr;
8808  UBVal = MinUB.get();
8809  }
8810  }
8811  Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8812  Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8813  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8814  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8815  if (!Upper || !Lower)
8816  return nullptr;
8817 
8818  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8819  Step, VarType, TestIsStrictOp,
8820  /*RoundToStep=*/true, Captures);
8821  if (!Diff.isUsable())
8822  return nullptr;
8823 
8824  // OpenMP runtime requires 32-bit or 64-bit loop variables.
8825  QualType Type = Diff.get()->getType();
8826  ASTContext &C = SemaRef.Context;
8827  bool UseVarType = VarType->hasIntegerRepresentation() &&
8828  C.getTypeSize(Type) > C.getTypeSize(VarType);
8829  if (!Type->isIntegerType() || UseVarType) {
8830  unsigned NewSize =
8831  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8832  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8834  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8835  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8836  Diff = SemaRef.PerformImplicitConversion(
8837  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8838  if (!Diff.isUsable())
8839  return nullptr;
8840  }
8841  }
8842  if (LimitedType) {
8843  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8844  if (NewSize != C.getTypeSize(Type)) {
8845  if (NewSize < C.getTypeSize(Type)) {
8846  assert(NewSize == 64 && "incorrect loop var size");
8847  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8848  << InitSrcRange << ConditionSrcRange;
8849  }
8850  QualType NewType = C.getIntTypeForBitwidth(
8851  NewSize, Type->hasSignedIntegerRepresentation() ||
8852  C.getTypeSize(Type) < NewSize);
8853  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8854  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8855  Sema::AA_Converting, true);
8856  if (!Diff.isUsable())
8857  return nullptr;
8858  }
8859  }
8860  }
8861 
8862  return Diff.get();
8863 }
8864 
8865 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8866  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8867  // Do not build for iterators, they cannot be used in non-rectangular loop
8868  // nests.
8869  if (LCDecl->getType()->isRecordType())
8870  return std::make_pair(nullptr, nullptr);
8871  // If we subtract, the min is in the condition, otherwise the min is in the
8872  // init value.
8873  Expr *MinExpr = nullptr;
8874  Expr *MaxExpr = nullptr;
8875  Expr *LBExpr = *TestIsLessOp ? LB : UB;
8876  Expr *UBExpr = *TestIsLessOp ? UB : LB;
8877  bool LBNonRect =
8878  *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
8879  bool UBNonRect =
8880  *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
8881  Expr *Lower =
8882  LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8883  Expr *Upper =
8884  UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8885  if (!Upper || !Lower)
8886  return std::make_pair(nullptr, nullptr);
8887 
8888  if (*TestIsLessOp)
8889  MinExpr = Lower;
8890  else
8891  MaxExpr = Upper;
8892 
8893  // Build minimum/maximum value based on number of iterations.
8894  QualType VarType = LCDecl->getType().getNonReferenceType();
8895 
8896  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8897  Step, VarType, TestIsStrictOp,
8898  /*RoundToStep=*/false, Captures);
8899  if (!Diff.isUsable())
8900  return std::make_pair(nullptr, nullptr);
8901 
8902  // ((Upper - Lower [- 1]) / Step) * Step
8903  // Parentheses (for dumping/debugging purposes only).
8904  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8905  if (!Diff.isUsable())
8906  return std::make_pair(nullptr, nullptr);
8907 
8908  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8909  if (!NewStep.isUsable())
8910  return std::make_pair(nullptr, nullptr);
8911  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8912  if (!Diff.isUsable())
8913  return std::make_pair(nullptr, nullptr);
8914 
8915  // Parentheses (for dumping/debugging purposes only).
8916  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8917  if (!Diff.isUsable())
8918  return std::make_pair(nullptr, nullptr);
8919 
8920  // Convert to the ptrdiff_t, if original type is pointer.
8921  if (VarType->isAnyPointerType() &&
8922  !SemaRef.Context.hasSameType(
8923  Diff.get()->getType(),
8924  SemaRef.Context.getUnsignedPointerDiffType())) {
8925  Diff = SemaRef.PerformImplicitConversion(
8926  Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8927  Sema::AA_Converting, /*AllowExplicit=*/true);
8928  }
8929  if (!Diff.isUsable())
8930  return std::make_pair(nullptr, nullptr);
8931 
8932  if (*TestIsLessOp) {
8933  // MinExpr = Lower;
8934  // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8935  Diff = SemaRef.BuildBinOp(
8936  S, DefaultLoc, BO_Add,
8937  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8938  Diff.get());
8939  if (!Diff.isUsable())
8940  return std::make_pair(nullptr, nullptr);
8941  } else {
8942  // MaxExpr = Upper;
8943  // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8944  Diff = SemaRef.BuildBinOp(
8945  S, DefaultLoc, BO_Sub,
8946  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8947  Diff.get());
8948  if (!Diff.isUsable())
8949  return std::make_pair(nullptr, nullptr);
8950  }
8951 
8952  // Convert to the original type.
8953  if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8954  Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8956  /*AllowExplicit=*/true);
8957  if (!Diff.isUsable())
8958  return std::make_pair(nullptr, nullptr);
8959 
8960  Sema::TentativeAnalysisScope Trap(SemaRef);
8961  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8962  if (!Diff.isUsable())
8963  return std::make_pair(nullptr, nullptr);
8964 
8965  if (*TestIsLessOp)
8966  MaxExpr = Diff.get();
8967  else
8968  MinExpr = Diff.get();
8969 
8970  return std::make_pair(MinExpr, MaxExpr);
8971 }
8972 
8973 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8974  if (InitDependOnLC || CondDependOnLC)
8975  return Condition;
8976  return nullptr;
8977 }
8978 
8979 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8980  Scope *S, Expr *Cond,
8981  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8982  // Do not build a precondition when the condition/initialization is dependent
8983  // to prevent pessimistic early loop exit.
8984  // TODO: this can be improved by calculating min/max values but not sure that
8985  // it will be very effective.
8986  if (CondDependOnLC || InitDependOnLC)
8987  return SemaRef
8989  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8990  SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8991  /*AllowExplicit=*/true)
8992  .get();
8993 
8994  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8995  Sema::TentativeAnalysisScope Trap(SemaRef);
8996 
8997  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8998  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8999  if (!NewLB.isUsable() || !NewUB.isUsable())
9000  return nullptr;
9001 
9002  ExprResult CondExpr =
9003  SemaRef.BuildBinOp(S, DefaultLoc,
9004  *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9005  : (TestIsStrictOp ? BO_GT : BO_GE),
9006  NewLB.get(), NewUB.get());
9007  if (CondExpr.isUsable()) {
9008  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
9009  SemaRef.Context.BoolTy))
9010  CondExpr = SemaRef.PerformImplicitConversion(
9011  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9012  /*AllowExplicit=*/true);
9013  }
9014 
9015  // Otherwise use original loop condition and evaluate it in runtime.
9016  return CondExpr.isUsable() ? CondExpr.get() : Cond;
9017 }
9018 
9019 /// Build reference expression to the counter be used for codegen.
9020 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9021  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9022  DSAStackTy &DSA) const {
9023  auto *VD = dyn_cast<VarDecl>(LCDecl);
9024  if (!VD) {
9025  VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9027  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9028  const DSAStackTy::DSAVarData Data =
9029  DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9030  // If the loop control decl is explicitly marked as private, do not mark it
9031  // as captured again.
9032  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9033  Captures.insert(std::make_pair(LCRef, Ref));
9034  return Ref;
9035  }
9036  return cast<DeclRefExpr>(LCRef);
9037 }
9038 
9039 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9040  if (LCDecl && !LCDecl->isInvalidDecl()) {
9041  QualType Type = LCDecl->getType().getNonReferenceType();
9042  VarDecl *PrivateVar = buildVarDecl(
9043  SemaRef, DefaultLoc, Type, LCDecl->getName(),
9044  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9045  isa<VarDecl>(LCDecl)
9046  ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9047  : nullptr);
9048  if (PrivateVar->isInvalidDecl())
9049  return nullptr;
9050  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9051  }
9052  return nullptr;
9053 }
9054 
9055 /// Build initialization of the counter to be used for codegen.
9057 
9058 /// Build step of the counter be used for codegen.
9059 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9060 
9061 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9062  Scope *S, Expr *Counter,
9063  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9064  Expr *Inc, OverloadedOperatorKind OOK) {
9065  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9066  if (!Cnt)
9067  return nullptr;
9068  if (Inc) {
9069  assert((OOK == OO_Plus || OOK == OO_Minus) &&
9070  "Expected only + or - operations for depend clauses.");
9071  BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9072  Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9073  if (!Cnt)
9074  return nullptr;
9075  }
9076  QualType VarType = LCDecl->getType().getNonReferenceType();
9077  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9078  !SemaRef.getLangOpts().CPlusPlus)
9079  return nullptr;
9080  // Upper - Lower
9081  Expr *Upper =
9082  *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9083  Expr *Lower =
9084  *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9085  if (!Upper || !Lower)
9086  return nullptr;
9087 
9088  ExprResult Diff = calculateNumIters(
9089  SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9090  /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9091  if (!Diff.isUsable())
9092  return nullptr;
9093 
9094  return Diff.get();
9095 }
9096 } // namespace
9097 
9099  assert(getLangOpts().OpenMP && "OpenMP is not active.");
9100  assert(Init && "Expected loop in canonical form.");
9101  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9102  if (AssociatedLoops > 0 &&
9103  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9104  DSAStack->loopStart();
9105  OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9106  *DSAStack, ForLoc);
9107  if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9108  if (ValueDecl *D = ISC.getLoopDecl()) {
9109  auto *VD = dyn_cast<VarDecl>(D);
9110  DeclRefExpr *PrivateRef = nullptr;
9111  if (!VD) {
9112  if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9113  VD = Private;
9114  } else {
9115  PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9116  /*WithInit=*/false);
9117  VD = cast<VarDecl>(PrivateRef->getDecl());
9118  }
9119  }
9120  DSAStack->addLoopControlVariable(D, VD);
9121  const Decl *LD = DSAStack->getPossiblyLoopCunter();
9122  if (LD != D->getCanonicalDecl()) {
9123  DSAStack->resetPossibleLoopCounter();
9124  if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9126  buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9128  ForLoc, /*RefersToCapture=*/true));
9129  }
9130  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9131  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9132  // Referenced in a Construct, C/C++]. The loop iteration variable in the
9133  // associated for-loop of a simd construct with just one associated
9134  // for-loop may be listed in a linear clause with a constant-linear-step
9135  // that is the increment of the associated for-loop. The loop iteration
9136  // variable(s) in the associated for-loop(s) of a for or parallel for
9137  // construct may be listed in a private or lastprivate clause.
9138  DSAStackTy::DSAVarData DVar =
9139  DSAStack->getTopDSA(D, /*FromParent=*/false);
9140  // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9141  // is declared in the loop and it is predetermined as a private.
9142  Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9143  OpenMPClauseKind PredeterminedCKind =
9144  isOpenMPSimdDirective(DKind)
9145  ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9146  : OMPC_private;
9147  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9148  DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9149  (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9150  DVar.CKind != OMPC_private))) ||
9151  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9152  DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9153  DKind == OMPD_parallel_master_taskloop ||
9154  DKind == OMPD_parallel_masked_taskloop ||
9155  isOpenMPDistributeDirective(DKind)) &&
9156  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9157  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9158  (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9159  Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9160  << getOpenMPClauseName(DVar.CKind)
9161  << getOpenMPDirectiveName(DKind)
9162  << getOpenMPClauseName(PredeterminedCKind);
9163  if (DVar.RefExpr == nullptr)
9164  DVar.CKind = PredeterminedCKind;
9165  reportOriginalDsa(*this, DSAStack, D, DVar,
9166  /*IsLoopIterVar=*/true);
9167  } else if (LoopDeclRefExpr) {
9168  // Make the loop iteration variable private (for worksharing
9169  // constructs), linear (for simd directives with the only one
9170  // associated loop) or lastprivate (for simd directives with several
9171  // collapsed or ordered loops).
9172  if (DVar.CKind == OMPC_unknown)
9173  DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9174  PrivateRef);
9175  }
9176  }
9177  }
9178  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9179  }
9180 }
9181 
9182 /// Called on a for stmt to check and extract its iteration space
9183 /// for further processing (such as collapsing).
9185  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9186  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9187  unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9188  Expr *OrderedLoopCountExpr,
9189  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9191  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9192  bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9193  // OpenMP [2.9.1, Canonical Loop Form]
9194  // for (init-expr; test-expr; incr-expr) structured-block
9195  // for (range-decl: range-expr) structured-block
9196  if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9197  S = CanonLoop->getLoopStmt();
9198  auto *For = dyn_cast_or_null<ForStmt>(S);
9199  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9200  // Ranged for is supported only in OpenMP 5.0.
9201  if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9202  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9203  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9204  << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9205  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9206  if (TotalNestedLoopCount > 1) {
9207  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9208  SemaRef.Diag(DSA.getConstructLoc(),
9209  diag::note_omp_collapse_ordered_expr)
9210  << 2 << CollapseLoopCountExpr->getSourceRange()
9211  << OrderedLoopCountExpr->getSourceRange();
9212  else if (CollapseLoopCountExpr)
9213  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9214  diag::note_omp_collapse_ordered_expr)
9215  << 0 << CollapseLoopCountExpr->getSourceRange();
9216  else
9217  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9218  diag::note_omp_collapse_ordered_expr)
9219  << 1 << OrderedLoopCountExpr->getSourceRange();
9220  }
9221  return true;
9222  }
9223  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9224  "No loop body.");
9225  // Postpone analysis in dependent contexts for ranged for loops.
9226  if (CXXFor && SemaRef.CurContext->isDependentContext())
9227  return false;
9228 
9229  OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9230  For ? For->getForLoc() : CXXFor->getForLoc());
9231 
9232  // Check init.
9233  Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9234  if (ISC.checkAndSetInit(Init))
9235  return true;
9236 
9237  bool HasErrors = false;
9238 
9239  // Check loop variable's type.
9240  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9241  // OpenMP [2.6, Canonical Loop Form]
9242  // Var is one of the following:
9243  // A variable of signed or unsigned integer type.
9244  // For C++, a variable of a random access iterator type.
9245  // For C, a variable of a pointer type.
9246  QualType VarType = LCDecl->getType().getNonReferenceType();
9247  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9248  !VarType->isPointerType() &&
9249  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9250  SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9251  << SemaRef.getLangOpts().CPlusPlus;
9252  HasErrors = true;
9253  }
9254 
9255  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9256  // a Construct
9257  // The loop iteration variable(s) in the associated for-loop(s) of a for or
9258  // parallel for construct is (are) private.
9259  // The loop iteration variable in the associated for-loop of a simd
9260  // construct with just one associated for-loop is linear with a
9261  // constant-linear-step that is the increment of the associated for-loop.
9262  // Exclude loop var from the list of variables with implicitly defined data
9263  // sharing attributes.
9264  VarsWithImplicitDSA.erase(LCDecl);
9265 
9266  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9267 
9268  // Check test-expr.
9269  HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9270 
9271  // Check incr-expr.
9272  HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9273  }
9274 
9275  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9276  return HasErrors;
9277 
9278  // Build the loop's iteration space representation.
9279  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9280  DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9281  ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9282  ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9283  (isOpenMPWorksharingDirective(DKind) ||
9285  isOpenMPTaskLoopDirective(DKind) ||
9286  isOpenMPDistributeDirective(DKind) ||
9288  Captures);
9289  ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9290  ISC.buildCounterVar(Captures, DSA);
9291  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9292  ISC.buildPrivateCounterVar();
9293  ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9294  ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9295  ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9296  ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9297  ISC.getConditionSrcRange();
9298  ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9299  ISC.getIncrementSrcRange();
9300  ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9301  ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9302  ISC.isStrictTestOp();
9303  std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9304  ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9305  ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9306  ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9307  ISC.buildFinalCondition(DSA.getCurScope());
9308  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9309  ISC.doesInitDependOnLC();
9310  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9311  ISC.doesCondDependOnLC();
9312  ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9313  ISC.getLoopDependentIdx();
9314 
9315  HasErrors |=
9316  (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9317  ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9318  ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9319  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9320  ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9321  ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9322  if (!HasErrors && DSA.isOrderedRegion()) {
9323  if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9324  if (CurrentNestedLoopCount <
9325  DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9326  DSA.getOrderedRegionParam().second->setLoopNumIterations(
9327  CurrentNestedLoopCount,
9328  ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9329  DSA.getOrderedRegionParam().second->setLoopCounter(
9330  CurrentNestedLoopCount,
9331  ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9332  }
9333  }
9334  for (auto &Pair : DSA.getDoacrossDependClauses()) {
9335  if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
9336  // Erroneous case - clause has some problems.
9337  continue;
9338  }
9339  if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
9340  Pair.second.size() <= CurrentNestedLoopCount) {
9341  // Erroneous case - clause has some problems.
9342  Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
9343  continue;
9344  }
9345  Expr *CntValue;
9346  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
9347  CntValue = ISC.buildOrderedLoopData(
9348  DSA.getCurScope(),
9349  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9350  Pair.first->getDependencyLoc());
9351  else
9352  CntValue = ISC.buildOrderedLoopData(
9353  DSA.getCurScope(),
9354  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9355  Pair.first->getDependencyLoc(),
9356  Pair.second[CurrentNestedLoopCount].first,
9357  Pair.second[CurrentNestedLoopCount].second);
9358  Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9359  }
9360  }
9361 
9362  return HasErrors;
9363 }
9364 
9365 /// Build 'VarRef = Start.
9366 static ExprResult
9368  ExprResult Start, bool IsNonRectangularLB,
9369  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9370  // Build 'VarRef = Start.
9371  ExprResult NewStart = IsNonRectangularLB
9372  ? Start.get()
9373  : tryBuildCapture(SemaRef, Start.get(), Captures);
9374  if (!NewStart.isUsable())
9375  return ExprError();
9376  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9377  VarRef.get()->getType())) {
9378  NewStart = SemaRef.PerformImplicitConversion(
9379  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9380  /*AllowExplicit=*/true);
9381  if (!NewStart.isUsable())
9382  return ExprError();
9383  }
9384 
9385  ExprResult Init =
9386  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9387  return Init;
9388 }
9389 
9390 /// Build 'VarRef = Start + Iter * Step'.
9392  Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9393  ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9394  bool IsNonRectangularLB,
9395  llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9396  // Add parentheses (for debugging purposes only).
9397  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9398  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9399  !Step.isUsable())
9400  return ExprError();
9401 
9402  ExprResult NewStep = Step;
9403  if (Captures)
9404  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9405  if (NewStep.isInvalid())
9406  return ExprError();
9407  ExprResult Update =
9408  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9409  if (!Update.isUsable())
9410  return ExprError();
9411 
9412  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9413  // 'VarRef = Start (+|-) Iter * Step'.
9414  if (!Start.isUsable())
9415  return ExprError();
9416  ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9417  if (!NewStart.isUsable())
9418  return ExprError();
9419  if (Captures && !IsNonRectangularLB)
9420  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9421  if (NewStart.isInvalid())
9422  return ExprError();
9423 
9424  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9425  ExprResult SavedUpdate = Update;
9426  ExprResult UpdateVal;
9427  if (VarRef.get()->getType()->isOverloadableType() ||
9428  NewStart.get()->getType()->isOverloadableType() ||
9429  Update.get()->getType()->isOverloadableType()) {
9430  Sema::TentativeAnalysisScope Trap(SemaRef);
9431 
9432  Update =
9433  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9434  if (Update.isUsable()) {
9435  UpdateVal =
9436  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9437  VarRef.get(), SavedUpdate.get());
9438  if (UpdateVal.isUsable()) {
9439  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9440  UpdateVal.get());
9441  }
9442  }
9443  }
9444 
9445  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9446  if (!Update.isUsable() || !UpdateVal.isUsable()) {
9447  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9448  NewStart.get(), SavedUpdate.get());
9449  if (!Update.isUsable())
9450  return ExprError();
9451 
9452  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9453  VarRef.get()->getType())) {
9455  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9456  if (!Update.isUsable())
9457  return ExprError();
9458  }
9459 
9460  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9461  }
9462  return Update;
9463 }
9464 
9465 /// Convert integer expression \a E to make it have at least \a Bits
9466 /// bits.
9467 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9468  if (E == nullptr)
9469  return ExprError();
9470  ASTContext &C = SemaRef.Context;
9471  QualType OldType = E->getType();
9472  unsigned HasBits = C.getTypeSize(OldType);
9473  if (HasBits >= Bits)
9474  return ExprResult(E);
9475  // OK to convert to signed, because new type has more bits than old.
9476  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9477  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9478  true);
9479 }
9480 
9481 /// Check if the given expression \a E is a constant integer that fits
9482 /// into \a Bits bits.
9483 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9484  if (E == nullptr)
9485  return false;
9486  if (std::optional<llvm::APSInt> Result =
9487  E->getIntegerConstantExpr(SemaRef.Context))
9488  return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9489  return false;
9490 }
9491 
9492 /// Build preinits statement for the given declarations.
9493 static Stmt *buildPreInits(ASTContext &Context,
9494  MutableArrayRef<Decl *> PreInits) {
9495  if (!PreInits.empty()) {
9496  return new (Context) DeclStmt(
9497  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9499  }
9500  return nullptr;
9501 }
9502 
9503 /// Build preinits statement for the given declarations.
9504 static Stmt *
9506  const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9507  if (!Captures.empty()) {
9508  SmallVector<Decl *, 16> PreInits;
9509  for (const auto &Pair : Captures)
9510  PreInits.push_back(Pair.second->getDecl());
9511  return buildPreInits(Context, PreInits);
9512  }
9513  return nullptr;
9514 }
9515 
9516 /// Build postupdate expression for the given list of postupdates expressions.
9517 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9518  Expr *PostUpdate = nullptr;
9519  if (!PostUpdates.empty()) {
9520  for (Expr *E : PostUpdates) {
9521  Expr *ConvE = S.BuildCStyleCastExpr(
9522  E->getExprLoc(),
9524  E->getExprLoc(), E)
9525  .get();
9526  PostUpdate = PostUpdate
9527  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9528  PostUpdate, ConvE)
9529  .get()
9530  : ConvE;
9531  }
9532  }
9533  return PostUpdate;
9534 }
9535 
9536 /// Called on a for stmt to check itself and nested loops (if any).
9537 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9538 /// number of collapsed loops otherwise.
9539 static unsigned
9540 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9541  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9542  DSAStackTy &DSA,
9543  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9545  unsigned NestedLoopCount = 1;
9546  bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9548 
9549  if (CollapseLoopCountExpr) {
9550  // Found 'collapse' clause - calculate collapse number.
9551  Expr::EvalResult Result;
9552  if (!CollapseLoopCountExpr->isValueDependent() &&
9553  CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9554  NestedLoopCount = Result.Val.getInt().getLimitedValue();
9555  } else {
9556  Built.clear(/*Size=*/1);
9557  return 1;
9558  }
9559  }
9560  unsigned OrderedLoopCount = 1;
9561  if (OrderedLoopCountExpr) {
9562  // Found 'ordered' clause - calculate collapse number.
9563  Expr::EvalResult EVResult;
9564  if (!OrderedLoopCountExpr->isValueDependent() &&
9565  OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9566  SemaRef.getASTContext())) {
9567  llvm::APSInt Result = EVResult.Val.getInt();
9568  if (Result.getLimitedValue() < NestedLoopCount) {
9569  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9570  diag::err_omp_wrong_ordered_loop_count)
9571  << OrderedLoopCountExpr->getSourceRange();
9572  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9573  diag::note_collapse_loop_count)
9574  << CollapseLoopCountExpr->getSourceRange();
9575  }
9576  OrderedLoopCount = Result.getLimitedValue();
9577  } else {
9578  Built.clear(/*Size=*/1);
9579  return 1;
9580  }
9581  }
9582  // This is helper routine for loop directives (e.g., 'for', 'simd',
9583  // 'for simd', etc.).
9584  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9585  unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9586  SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9589  SupportsNonPerfectlyNested, NumLoops,
9590  [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9591  CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9592  &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9594  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9595  NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9596  VarsWithImplicitDSA, IterSpaces, Captures))
9597  return true;
9598  if (Cnt > 0 && Cnt >= NestedLoopCount &&
9599  IterSpaces[Cnt].CounterVar) {
9600  // Handle initialization of captured loop iterator variables.
9601  auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9602  if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9603  Captures[DRE] = DRE;
9604  }
9605  }
9606  return false;
9607  },
9608  [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9609  Stmt *DependentPreInits = Transform->getPreInits();
9610  if (!DependentPreInits)
9611  return;
9612  for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9613  auto *D = cast<VarDecl>(C);
9614  DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9615  Transform->getBeginLoc());
9616  Captures[Ref] = Ref;
9617  }
9618  }))
9619  return 0;
9620 
9621  Built.clear(/* size */ NestedLoopCount);
9622 
9623  if (SemaRef.CurContext->isDependentContext())
9624  return NestedLoopCount;
9625 
9626  // An example of what is generated for the following code:
9627  //
9628  // #pragma omp simd collapse(2) ordered(2)
9629  // for (i = 0; i < NI; ++i)
9630  // for (k = 0; k < NK; ++k)
9631  // for (j = J0; j < NJ; j+=2) {
9632  // <loop body>
9633  // }
9634  //
9635  // We generate the code below.
9636  // Note: the loop body may be outlined in CodeGen.
9637  // Note: some counters may be C++ classes, operator- is used to find number of
9638  // iterations and operator+= to calculate counter value.
9639  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9640  // or i64 is currently supported).
9641  //
9642  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9643  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9644  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9645  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9646  // // similar updates for vars in clauses (e.g. 'linear')
9647  // <loop body (using local i and j)>
9648  // }
9649  // i = NI; // assign final values of counters
9650  // j = NJ;
9651  //
9652 
9653  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9654  // the iteration counts of the collapsed for loops.
9655  // Precondition tests if there is at least one iteration (all conditions are
9656  // true).
9657  auto PreCond = ExprResult(IterSpaces[0].PreCond);
9658  Expr *N0 = IterSpaces[0].NumIterations;
9659  ExprResult LastIteration32 =
9660  widenIterationCount(/*Bits=*/32,
9661  SemaRef
9662  .PerformImplicitConversion(
9663  N0->IgnoreImpCasts(), N0->getType(),
9664  Sema::AA_Converting, /*AllowExplicit=*/true)
9665  .get(),
9666  SemaRef);
9667  ExprResult LastIteration64 = widenIterationCount(
9668  /*Bits=*/64,
9669  SemaRef
9670  .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9672  /*AllowExplicit=*/true)
9673  .get(),
9674  SemaRef);
9675 
9676  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9677  return NestedLoopCount;
9678 
9679  ASTContext &C = SemaRef.Context;
9680  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9681 
9682  Scope *CurScope = DSA.getCurScope();
9683  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9684  if (PreCond.isUsable()) {
9685  PreCond =
9686  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9687  PreCond.get(), IterSpaces[Cnt].PreCond);
9688  }
9689  Expr *N = IterSpaces[Cnt].NumIterations;
9690  SourceLocation Loc = N->getExprLoc();
9691  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9692  if (LastIteration32.isUsable())
9693  LastIteration32 = SemaRef.BuildBinOp(
9694  CurScope, Loc, BO_Mul, LastIteration32.get(),
9695  SemaRef
9698  /*AllowExplicit=*/true)
9699  .get());
9700  if (LastIteration64.isUsable())
9701  LastIteration64 = SemaRef.BuildBinOp(
9702  CurScope, Loc, BO_Mul, LastIteration64.get(),
9703  SemaRef
9706  /*AllowExplicit=*/true)
9707  .get());
9708  }
9709 
9710  // Choose either the 32-bit or 64-bit version.
9711  ExprResult LastIteration = LastIteration64;
9712  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9713  (LastIteration32.isUsable() &&
9714  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9715  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9716  fitsInto(
9717  /*Bits=*/32,
9718  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9719  LastIteration64.get(), SemaRef))))
9720  LastIteration = LastIteration32;
9721  QualType VType = LastIteration.get()->getType();
9722  QualType RealVType = VType;
9723  QualType StrideVType = VType;
9724  if (isOpenMPTaskLoopDirective(DKind)) {
9725  VType =
9726  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9727  StrideVType =
9728  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9729  }
9730 
9731  if (!LastIteration.isUsable())
9732  return 0;
9733 
9734  // Save the number of iterations.
9735  ExprResult NumIterations = LastIteration;
9736  {
9737  LastIteration = SemaRef.BuildBinOp(
9738  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9739  LastIteration.get(),
9740  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9741  if (!LastIteration.isUsable())
9742  return 0;
9743  }
9744 
9745  // Calculate the last iteration number beforehand instead of doing this on
9746  // each iteration. Do not do this if the number of iterations may be kfold-ed.
9747  bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9748  ExprResult CalcLastIteration;
9749  if (!IsConstant) {
9750  ExprResult SaveRef =
9751  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9752  LastIteration = SaveRef;
9753 
9754  // Prepare SaveRef + 1.
9755  NumIterations = SemaRef.BuildBinOp(
9756  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9757  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9758  if (!NumIterations.isUsable())
9759  return 0;
9760  }
9761 
9762  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9763 
9764  // Build variables passed into runtime, necessary for worksharing directives.
9765  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9767  isOpenMPDistributeDirective(DKind) ||
9770  // Lower bound variable, initialized with zero.
9771  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9772  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9773  SemaRef.AddInitializerToDecl(LBDecl,
9774  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9775  /*DirectInit*/ false);
9776 
9777  // Upper bound variable, initialized with last iteration number.
9778  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9779  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9780  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9781  /*DirectInit*/ false);
9782 
9783  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9784  // This will be used to implement clause 'lastprivate'.
9785  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9786  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9787  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9788  SemaRef.AddInitializerToDecl(ILDecl,
9789  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9790  /*DirectInit*/ false);
9791 
9792  // Stride variable returned by runtime (we initialize it to 1 by default).
9793  VarDecl *STDecl =
9794  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9795  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9796  SemaRef.AddInitializerToDecl(STDecl,
9797  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9798  /*DirectInit*/ false);
9799 
9800  // Build expression: UB = min(UB, LastIteration)
9801  // It is necessary for CodeGen of directives with static scheduling.
9802  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9803  UB.get(), LastIteration.get());
9804  ExprResult CondOp = SemaRef.ActOnConditionalOp(
9805  LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9806  LastIteration.get(), UB.get());
9807  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9808  CondOp.get());
9809  EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9810 
9811  // If we have a combined directive that combines 'distribute', 'for' or
9812  // 'simd' we need to be able to access the bounds of the schedule of the
9813  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9814  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9815  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9816  // Lower bound variable, initialized with zero.
9817  VarDecl *CombLBDecl =
9818  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9819  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9820  SemaRef.AddInitializerToDecl(
9821  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9822  /*DirectInit*/ false);
9823 
9824  // Upper bound variable, initialized with last iteration number.
9825  VarDecl *CombUBDecl =
9826  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9827  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9828  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9829  /*DirectInit*/ false);
9830 
9831  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9832  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9833  ExprResult CombCondOp =
9834  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9835  LastIteration.get(), CombUB.get());
9836  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9837  CombCondOp.get());
9838  CombEUB =
9839  SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9840 
9841  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9842  // We expect to have at least 2 more parameters than the 'parallel'
9843  // directive does - the lower and upper bounds of the previous schedule.
9844  assert(CD->getNumParams() >= 4 &&
9845  "Unexpected number of parameters in loop combined directive");
9846 
9847  // Set the proper type for the bounds given what we learned from the
9848  // enclosed loops.
9849  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9850  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9851 
9852  // Previous lower and upper bounds are obtained from the region
9853  // parameters.
9854  PrevLB =
9855  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9856  PrevUB =
9857  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9858  }
9859  }
9860 
9861  // Build the iteration variable and its initialization before loop.
9862  ExprResult IV;
9863  ExprResult Init, CombInit;
9864  {
9865  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9866  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9867  Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9869  isOpenMPTaskLoopDirective(DKind) ||
9870  isOpenMPDistributeDirective(DKind) ||
9872  ? LB.get()
9873  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9874  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9875  Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9876 
9877  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9878  Expr *CombRHS =
9879  (isOpenMPWorksharingDirective(DKind) ||
9881  isOpenMPTaskLoopDirective(DKind) ||
9883  ? CombLB.get()
9884  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9885  CombInit =
9886  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9887  CombInit =
9888  SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9889  }
9890  }
9891 
9892  bool UseStrictCompare =
9893  RealVType->hasUnsignedIntegerRepresentation() &&
9894  llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9895  return LIS.IsStrictCompare;
9896  });
9897  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9898  // unsigned IV)) for worksharing loops.
9899  SourceLocation CondLoc = AStmt->getBeginLoc();
9900  Expr *BoundUB = UB.get();
9901  if (UseStrictCompare) {
9902  BoundUB =
9903  SemaRef
9904  .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9905  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9906  .get();
9907  BoundUB =
9908  SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9909  }
9910  ExprResult Cond =
9911  (isOpenMPWorksharingDirective(DKind) ||
9915  ? SemaRef.BuildBinOp(CurScope, CondLoc,
9916  UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9917  BoundUB)
9918  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9919  NumIterations.get());
9920  ExprResult CombDistCond;
9921  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9922  CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9923  NumIterations.get());
9924  }
9925 
9926  ExprResult CombCond;
9927  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9928  Expr *BoundCombUB = CombUB.get();
9929  if (UseStrictCompare) {
9930  BoundCombUB =
9931  SemaRef
9932  .BuildBinOp(
9933  CurScope, CondLoc, BO_Add, BoundCombUB,
9934  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9935  .get();
9936  BoundCombUB =
9937  SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9938  .get();
9939  }
9940  CombCond =
9941  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9942  IV.get(), BoundCombUB);
9943  }
9944  // Loop increment (IV = IV + 1)
9945  SourceLocation IncLoc = AStmt->getBeginLoc();
9946  ExprResult Inc =
9947  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9948  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9949  if (!Inc.isUsable())
9950  return 0;
9951  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9952  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9953  if (!Inc.isUsable())
9954  return 0;
9955 
9956  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9957  // Used for directives with static scheduling.
9958  // In combined construct, add combined version that use CombLB and CombUB
9959  // base variables for the update
9960  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9963  isOpenMPDistributeDirective(DKind) ||
9965  // LB + ST
9966  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9967  if (!NextLB.isUsable())
9968  return 0;
9969  // LB = LB + ST
9970  NextLB =
9971  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9972  NextLB =
9973  SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9974  if (!NextLB.isUsable())
9975  return 0;
9976  // UB + ST
9977  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9978  if (!NextUB.isUsable())
9979  return 0;
9980  // UB = UB + ST
9981  NextUB =
9982  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9983  NextUB =
9984  SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9985  if (!NextUB.isUsable())
9986  return 0;
9987  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9988  CombNextLB =
9989  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9990  if (!NextLB.isUsable())
9991  return 0;
9992  // LB = LB + ST
9993  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9994  CombNextLB.get());
9995  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9996  /*DiscardedValue*/ false);
9997  if (!CombNextLB.isUsable())
9998  return 0;
9999  // UB + ST
10000  CombNextUB =
10001  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10002  if (!CombNextUB.isUsable())
10003  return 0;
10004  // UB = UB + ST
10005  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10006  CombNextUB.get());
10007  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10008  /*DiscardedValue*/ false);
10009  if (!CombNextUB.isUsable())
10010  return 0;
10011  }
10012  }
10013 
10014  // Create increment expression for distribute loop when combined in a same
10015  // directive with for as IV = IV + ST; ensure upper bound expression based
10016  // on PrevUB instead of NumIterations - used to implement 'for' when found
10017  // in combination with 'distribute', like in 'distribute parallel for'
10018  SourceLocation DistIncLoc = AStmt->getBeginLoc();
10019  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10020  if (isOpenMPLoopBoundSharingDirective(DKind)) {
10021  DistCond = SemaRef.BuildBinOp(
10022  CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10023  assert(DistCond.isUsable() && "distribute cond expr was not built");
10024 
10025  DistInc =
10026  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10027  assert(DistInc.isUsable() && "distribute inc expr was not built");
10028  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10029  DistInc.get());
10030  DistInc =
10031  SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10032  assert(DistInc.isUsable() && "distribute inc expr was not built");
10033 
10034  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10035  // construct
10036  ExprResult NewPrevUB = PrevUB;
10037  SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10038  if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10039  PrevUB.get()->getType())) {
10040  NewPrevUB = SemaRef.BuildCStyleCastExpr(
10041  DistEUBLoc,
10042  SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10043  DistEUBLoc, NewPrevUB.get());
10044  if (!NewPrevUB.isUsable())
10045  return 0;
10046  }
10047  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10048  UB.get(), NewPrevUB.get());
10049  ExprResult CondOp = SemaRef.ActOnConditionalOp(
10050  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10051  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10052  CondOp.get());
10053  PrevEUB =
10054  SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10055 
10056  // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10057  // parallel for is in combination with a distribute directive with
10058  // schedule(static, 1)
10059  Expr *BoundPrevUB = PrevUB.get();
10060  if (UseStrictCompare) {
10061  BoundPrevUB =
10062  SemaRef
10063  .BuildBinOp(
10064  CurScope, CondLoc, BO_Add, BoundPrevUB,
10065  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10066  .get();
10067  BoundPrevUB =
10068  SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10069  .get();
10070  }
10071  ParForInDistCond =
10072  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10073  IV.get(), BoundPrevUB);
10074  }
10075 
10076  // Build updates and final values of the loop counters.
10077  bool HasErrors = false;
10078  Built.Counters.resize(NestedLoopCount);
10079  Built.Inits.resize(NestedLoopCount);
10080  Built.Updates.resize(NestedLoopCount);
10081  Built.Finals.resize(NestedLoopCount);
10082  Built.DependentCounters.resize(NestedLoopCount);
10083  Built.DependentInits.resize(NestedLoopCount);
10084  Built.FinalsConditions.resize(NestedLoopCount);
10085  {
10086  // We implement the following algorithm for obtaining the
10087  // original loop iteration variable values based on the
10088  // value of the collapsed loop iteration variable IV.
10089  //
10090  // Let n+1 be the number of collapsed loops in the nest.
10091  // Iteration variables (I0, I1, .... In)
10092  // Iteration counts (N0, N1, ... Nn)
10093  //
10094  // Acc = IV;
10095  //
10096  // To compute Ik for loop k, 0 <= k <= n, generate:
10097  // Prod = N(k+1) * N(k+2) * ... * Nn;
10098  // Ik = Acc / Prod;
10099  // Acc -= Ik * Prod;
10100  //
10101  ExprResult Acc = IV;
10102  for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10103  LoopIterationSpace &IS = IterSpaces[Cnt];
10104  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10105  ExprResult Iter;
10106 
10107  // Compute prod
10108  ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10109  for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10110  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10111  IterSpaces[K].NumIterations);
10112 
10113  // Iter = Acc / Prod
10114  // If there is at least one more inner loop to avoid
10115  // multiplication by 1.
10116  if (Cnt + 1 < NestedLoopCount)
10117  Iter =
10118  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10119  else
10120  Iter = Acc;
10121  if (!Iter.isUsable()) {
10122  HasErrors = true;
10123  break;
10124  }
10125 
10126  // Update Acc:
10127  // Acc -= Iter * Prod
10128  // Check if there is at least one more inner loop to avoid
10129  // multiplication by 1.
10130  if (Cnt + 1 < NestedLoopCount)
10131  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10132  Prod.get());
10133  else
10134  Prod = Iter;
10135  Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10136 
10137  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10138  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10139  DeclRefExpr *CounterVar = buildDeclRefExpr(
10140  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10141  /*RefersToCapture=*/true);
10142  ExprResult Init =
10143  buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10144  IS.CounterInit, IS.IsNonRectangularLB, Captures);
10145  if (!Init.isUsable()) {
10146  HasErrors = true;
10147  break;
10148  }
10150  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10151  IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10152  if (!Update.isUsable()) {
10153  HasErrors = true;
10154  break;
10155  }
10156 
10157  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10158  ExprResult Final =
10159  buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10160  IS.CounterInit, IS.NumIterations, IS.CounterStep,
10161  IS.Subtract, IS.IsNonRectangularLB, &Captures);
10162  if (!Final.isUsable()) {
10163  HasErrors = true;
10164  break;
10165  }
10166 
10167  if (!Update.isUsable() || !Final.isUsable()) {
10168  HasErrors = true;
10169  break;
10170  }
10171  // Save results
10172  Built.Counters[Cnt] = IS.CounterVar;
10173  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10174  Built.Inits[Cnt] = Init.get();
10175  Built.Updates[Cnt] = Update.get();
10176  Built.Finals[Cnt] = Final.get();
10177  Built.DependentCounters[Cnt] = nullptr;
10178  Built.DependentInits[Cnt] = nullptr;
10179  Built.FinalsConditions[Cnt] = nullptr;
10180  if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10181  Built.DependentCounters[Cnt] =
10182  Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
10183  Built.DependentInits[Cnt] =
10184  Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
10185  Built.FinalsConditions[Cnt] = IS.FinalCondition;
10186  }
10187  }
10188  }
10189 
10190  if (HasErrors)
10191  return 0;
10192 
10193  // Save results
10194  Built.IterationVarRef = IV.get();
10195  Built.LastIteration = LastIteration.get();
10196  Built.NumIterations = NumIterations.get();
10197  Built.CalcLastIteration = SemaRef
10198  .ActOnFinishFullExpr(CalcLastIteration.get(),
10199  /*DiscardedValue=*/false)
10200  .get();
10201  Built.PreCond = PreCond.get();
10202  Built.PreInits = buildPreInits(C, Captures);
10203  Built.Cond = Cond.get();
10204  Built.Init = Init.get();
10205  Built.Inc = Inc.get();
10206  Built.LB = LB.get();
10207  Built.UB = UB.get();
10208  Built.IL = IL.get();
10209  Built.ST = ST.get();
10210  Built.EUB = EUB.get();
10211  Built.NLB = NextLB.get();
10212  Built.NUB = NextUB.get();
10213  Built.PrevLB = PrevLB.get();
10214  Built.PrevUB = PrevUB.get();
10215  Built.DistInc = DistInc.get();
10216  Built.PrevEUB = PrevEUB.get();
10217  Built.DistCombinedFields.LB = CombLB.get();
10218  Built.DistCombinedFields.UB = CombUB.get();
10219  Built.DistCombinedFields.EUB = CombEUB.get();
10220  Built.DistCombinedFields.Init = CombInit.get();
10221  Built.DistCombinedFields.Cond = CombCond.get();
10222  Built.DistCombinedFields.NLB = CombNextLB.get();
10223  Built.DistCombinedFields.NUB = CombNextUB.get();
10224  Built.DistCombinedFields.DistCond = CombDistCond.get();
10225  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10226 
10227  return NestedLoopCount;
10228 }
10229 
10231  auto CollapseClauses =
10232  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10233  if (CollapseClauses.begin() != CollapseClauses.end())
10234  return (*CollapseClauses.begin())->getNumForLoops();
10235  return nullptr;
10236 }
10237 
10239  auto OrderedClauses =
10240  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10241  if (OrderedClauses.begin() != OrderedClauses.end())
10242  return (*OrderedClauses.begin())->getNumForLoops();
10243  return nullptr;
10244 }
10245 
10247  const ArrayRef<OMPClause *> Clauses) {
10248  const OMPSafelenClause *Safelen = nullptr;
10249  const OMPSimdlenClause *Simdlen = nullptr;
10250 
10251  for (const OMPClause *Clause : Clauses) {
10252  if (Clause->getClauseKind() == OMPC_safelen)
10253  Safelen = cast<OMPSafelenClause>(Clause);
10254  else if (Clause->getClauseKind() == OMPC_simdlen)
10255  Simdlen = cast<OMPSimdlenClause>(Clause);
10256  if (Safelen && Simdlen)
10257  break;
10258  }
10259 
10260  if (Simdlen && Safelen) {
10261  const Expr *SimdlenLength = Simdlen->getSimdlen();
10262  const Expr *SafelenLength = Safelen->getSafelen();
10263  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10264  SimdlenLength->isInstantiationDependent() ||
10265  SimdlenLength->containsUnexpandedParameterPack())
10266  return false;
10267  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10268  SafelenLength->isInstantiationDependent() ||
10269  SafelenLength->containsUnexpandedParameterPack())
10270  return false;
10271  Expr::EvalResult SimdlenResult, SafelenResult;
10272  SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10273  SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10274  llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10275  llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10276  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10277  // If both simdlen and safelen clauses are specified, the value of the
10278  // simdlen parameter must be less than or equal to the value of the safelen
10279  // parameter.
10280  if (SimdlenRes > SafelenRes) {
10281  S.Diag(SimdlenLength->getExprLoc(),
10282  diag::err_omp_wrong_simdlen_safelen_values)
10283  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10284  return true;
10285  }
10286  }
10287  return false;
10288 }
10289 
10290 StmtResult
10292  SourceLocation StartLoc, SourceLocation EndLoc,
10293  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10294  if (!AStmt)
10295  return StmtError();
10296 
10297  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10299  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10300  // define the nested loops number.
10301  unsigned NestedLoopCount = checkOpenMPLoop(
10302  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10303  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10304  if (NestedLoopCount == 0)
10305  return StmtError();
10306 
10307  assert((CurContext->isDependentContext() || B.builtAll()) &&
10308  "omp simd loop exprs were not built");
10309 
10310  if (!CurContext->isDependentContext()) {
10311  // Finalize the clauses that need pre-built expressions for CodeGen.
10312  for (OMPClause *C : Clauses) {
10313  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10314  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10315  B.NumIterations, *this, CurScope,
10316  DSAStack))
10317  return StmtError();
10318  }
10319  }
10320 
10321  if (checkSimdlenSafelenSpecified(*this, Clauses))
10322  return StmtError();
10323 
10325  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10326  Clauses, AStmt, B);
10327 }
10328 
10329 StmtResult
10331  SourceLocation StartLoc, SourceLocation EndLoc,
10332  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10333  if (!AStmt)
10334  return StmtError();
10335 
10336  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10338  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10339  // define the nested loops number.
10340  unsigned NestedLoopCount = checkOpenMPLoop(
10341  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10342  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10343  if (NestedLoopCount == 0)
10344  return StmtError();
10345 
10346  assert((CurContext->isDependentContext() || B.builtAll()) &&
10347  "omp for loop exprs were not built");
10348 
10349  if (!CurContext->isDependentContext()) {
10350  // Finalize the clauses that need pre-built expressions for CodeGen.
10351  for (OMPClause *C : Clauses) {
10352  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10353  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10354  B.NumIterations, *this, CurScope,
10355  DSAStack))
10356  return StmtError();
10357  }
10358  }
10359 
10361  return OMPForDirective::Create(
10362  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10363  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10364 }
10365 
10367  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10368  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10369  if (!AStmt)
10370  return StmtError();
10371 
10372  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10374  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10375  // define the nested loops number.
10376  unsigned NestedLoopCount =
10377  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10378  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10379  VarsWithImplicitDSA, B);
10380  if (NestedLoopCount == 0)
10381  return StmtError();
10382 
10383  assert((CurContext->isDependentContext() || B.builtAll()) &&
10384  "omp for simd loop exprs were not built");
10385 
10386  if (!CurContext->isDependentContext()) {
10387  // Finalize the clauses that need pre-built expressions for CodeGen.
10388  for (OMPClause *C : Clauses) {
10389  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10390  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10391  B.NumIterations, *this, CurScope,
10392  DSAStack))
10393  return StmtError();
10394  }
10395  }
10396 
10397  if (checkSimdlenSafelenSpecified(*this, Clauses))
10398  return StmtError();
10399 
10401  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10402  Clauses, AStmt, B);
10403 }
10404 
10406  Stmt *AStmt,
10407  SourceLocation StartLoc,
10408  SourceLocation EndLoc) {
10409  if (!AStmt)
10410  return StmtError();
10411 
10412  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10413  auto BaseStmt = AStmt;
10414  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10415  BaseStmt = CS->getCapturedStmt();
10416  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10417  auto S = C->children();
10418  if (S.begin() == S.end())
10419  return StmtError();
10420  // All associated statements must be '#pragma omp section' except for
10421  // the first one.
10422  for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10423  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10424  if (SectionStmt)
10425  Diag(SectionStmt->getBeginLoc(),
10426  diag::err_omp_sections_substmt_not_section);
10427  return StmtError();
10428  }
10429  cast<OMPSectionDirective>(SectionStmt)
10430  ->setHasCancel(DSAStack->isCancelRegion());
10431  }
10432  } else {
10433  Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10434  return StmtError();
10435  }
10436 
10438 
10439  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10440  DSAStack->getTaskgroupReductionRef(),
10441  DSAStack->isCancelRegion());
10442 }
10443 
10445  SourceLocation StartLoc,
10446  SourceLocation EndLoc) {
10447  if (!AStmt)
10448  return StmtError();
10449 
10451  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10452 
10453  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10454  DSAStack->isCancelRegion());
10455 }
10456 
10458  E = E->IgnoreParenCasts()->IgnoreImplicit();
10459  if (auto *CE = dyn_cast<CallExpr>(E))
10460  if (CE->getDirectCallee())
10461  return E;
10462  return nullptr;
10463 }
10464 
10466  Stmt *AStmt,
10467  SourceLocation StartLoc,
10468  SourceLocation EndLoc) {
10469  if (!AStmt)
10470  return StmtError();
10471 
10472  Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10473 
10474  // 5.1 OpenMP
10475  // expression-stmt : an expression statement with one of the following forms:
10476  // expression = target-call ( [expression-list] );
10477  // target-call ( [expression-list] );
10478 
10479  SourceLocation TargetCallLoc;
10480 
10481  if (!CurContext->isDependentContext()) {
10482  Expr *TargetCall = nullptr;
10483 
10484  auto *E = dyn_cast<Expr>(S);
10485  if (!E) {
10486  Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10487  return StmtError();
10488  }
10489 
10490  E = E->IgnoreParenCasts()->IgnoreImplicit();
10491 
10492  if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10493  if (BO->getOpcode() == BO_Assign)
10494  TargetCall = getDirectCallExpr(BO->getRHS());
10495  } else {
10496  if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10497  if (COCE->getOperator() == OO_Equal)
10498  TargetCall = getDirectCallExpr(COCE->getArg(1));
10499  if (!TargetCall)
10500  TargetCall = getDirectCallExpr(E);
10501  }
10502  if (!TargetCall) {
10503  Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10504  return StmtError();
10505  }
10506  TargetCallLoc = TargetCall->getExprLoc();
10507  }
10508 
10510 
10511  return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10512  TargetCallLoc);
10513 }
10514 
10517  DSAStackTy *Stack) {
10518  bool ErrorFound = false;
10519  for (OMPClause *C : Clauses) {
10520  if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10521  for (Expr *RefExpr : LPC->varlists()) {
10522  SourceLocation ELoc;
10523  SourceRange ERange;
10524  Expr *SimpleRefExpr = RefExpr;
10525  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10526  if (ValueDecl *D = Res.first) {
10527  auto &&Info = Stack->isLoopControlVariable(D);
10528  if (!Info.first) {
10529  S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10530  << getOpenMPDirectiveName(K);
10531  ErrorFound = true;
10532  }
10533  }
10534  }
10535  }
10536  }
10537  return ErrorFound;
10538 }
10539 
10541  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10542  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10543  if (!AStmt)
10544  return StmtError();
10545 
10546  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10547  // A list item may not appear in a lastprivate clause unless it is the
10548  // loop iteration variable of a loop that is associated with the construct.
10549  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10550  return StmtError();
10551 
10552  auto *CS = cast<CapturedStmt>(AStmt);
10553  // 1.2.2 OpenMP Language Terminology
10554  // Structured block - An executable statement with a single entry at the
10555  // top and a single exit at the bottom.
10556  // The point of exit cannot be a branch out of the structured block.
10557  // longjmp() and throw() must not violate the entry/exit criteria.
10558  CS->getCapturedDecl()->setNothrow();
10559 
10561  // In presence of clause 'collapse', it will define the nested loops number.
10562  unsigned NestedLoopCount = checkOpenMPLoop(
10563  OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10564  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10565  if (NestedLoopCount == 0)
10566  return StmtError();
10567 
10568  assert((CurContext->isDependentContext() || B.builtAll()) &&
10569  "omp loop exprs were not built");
10570 
10572  return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10573  NestedLoopCount, Clauses, AStmt, B);
10574 }
10575 
10577  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10578  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10579  if (!AStmt)
10580  return StmtError();
10581 
10582  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10583  // A list item may not appear in a lastprivate clause unless it is the
10584  // loop iteration variable of a loop that is associated with the construct.
10585  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10586  return StmtError();
10587 
10588  auto *CS = cast<CapturedStmt>(AStmt);
10589  // 1.2.2 OpenMP Language Terminology
10590  // Structured block - An executable statement with a single entry at the
10591  // top and a single exit at the bottom.
10592  // The point of exit cannot be a branch out of the structured block.
10593  // longjmp() and throw() must not violate the entry/exit criteria.
10594  CS->getCapturedDecl()->setNothrow();
10595  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10596  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10597  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10598  // 1.2.2 OpenMP Language Terminology
10599  // Structured block - An executable statement with a single entry at the
10600  // top and a single exit at the bottom.
10601  // The point of exit cannot be a branch out of the structured block.
10602  // longjmp() and throw() must not violate the entry/exit criteria.
10603  CS->getCapturedDecl()->setNothrow();
10604  }
10605 
10607  // In presence of clause 'collapse', it will define the nested loops number.
10608  unsigned NestedLoopCount =
10609  checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10610  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10611  VarsWithImplicitDSA, B);
10612  if (NestedLoopCount == 0)
10613  return StmtError();
10614 
10615  assert((CurContext->isDependentContext() || B.builtAll()) &&
10616  "omp loop exprs were not built");
10617 
10619  DSAStack->setParentTeamsRegionLoc(StartLoc);
10620 
10622  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10623 }
10624 
10626  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10627  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10628  if (!AStmt)
10629  return StmtError();
10630 
10631  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10632  // A list item may not appear in a lastprivate clause unless it is the
10633  // loop iteration variable of a loop that is associated with the construct.
10634  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10635  DSAStack))
10636  return StmtError();
10637 
10638  auto *CS = cast<CapturedStmt>(AStmt);
10639  // 1.2.2 OpenMP Language Terminology
10640  // Structured block - An executable statement with a single entry at the
10641  // top and a single exit at the bottom.
10642  // The point of exit cannot be a branch out of the structured block.
10643  // longjmp() and throw() must not violate the entry/exit criteria.
10644  CS->getCapturedDecl()->setNothrow();
10645  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10646  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10647  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10648  // 1.2.2 OpenMP Language Terminology
10649  // Structured block - An executable statement with a single entry at the
10650  // top and a single exit at the bottom.
10651  // The point of exit cannot be a branch out of the structured block.
10652  // longjmp() and throw() must not violate the entry/exit criteria.
10653  CS->getCapturedDecl()->setNothrow();
10654  }
10655 
10657  // In presence of clause 'collapse', it will define the nested loops number.
10658  unsigned NestedLoopCount =
10659  checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10660  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10661  VarsWithImplicitDSA, B);
10662  if (NestedLoopCount == 0)
10663  return StmtError();
10664 
10665  assert((CurContext->isDependentContext() || B.builtAll()) &&
10666  "omp loop exprs were not built");
10667 
10669 
10671  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10672 }
10673 
10675  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10676  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10677  if (!AStmt)
10678  return StmtError();
10679 
10680  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10681  // A list item may not appear in a lastprivate clause unless it is the
10682  // loop iteration variable of a loop that is associated with the construct.
10683  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10684  return StmtError();
10685 
10686  auto *CS = cast<CapturedStmt>(AStmt);
10687  // 1.2.2 OpenMP Language Terminology
10688  // Structured block - An executable statement with a single entry at the
10689  // top and a single exit at the bottom.
10690  // The point of exit cannot be a branch out of the structured block.
10691  // longjmp() and throw() must not violate the entry/exit criteria.
10692  CS->getCapturedDecl()->setNothrow();
10693  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10694  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10695  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10696  // 1.2.2 OpenMP Language Terminology
10697  // Structured block - An executable statement with a single entry at the
10698  // top and a single exit at the bottom.
10699  // The point of exit cannot be a branch out of the structured block.
10700  // longjmp() and throw() must not violate the entry/exit criteria.
10701  CS->getCapturedDecl()->setNothrow();
10702  }
10703 
10705  // In presence of clause 'collapse', it will define the nested loops number.
10706  unsigned NestedLoopCount =
10707  checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10708  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10709  VarsWithImplicitDSA, B);
10710  if (NestedLoopCount == 0)
10711  return StmtError();
10712 
10713  assert((CurContext->isDependentContext() || B.builtAll()) &&
10714  "omp loop exprs were not built");
10715 
10717 
10719  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10720 }
10721 
10723  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10724  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10725  if (!AStmt)
10726  return StmtError();
10727 
10728  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10729  // A list item may not appear in a lastprivate clause unless it is the
10730  // loop iteration variable of a loop that is associated with the construct.
10731  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10732  DSAStack))
10733  return StmtError();
10734 
10735  auto *CS = cast<CapturedStmt>(AStmt);
10736  // 1.2.2 OpenMP Language Terminology
10737  // Structured block - An executable statement with a single entry at the
10738  // top and a single exit at the bottom.
10739  // The point of exit cannot be a branch out of the structured block.
10740  // longjmp() and throw() must not violate the entry/exit criteria.
10741  CS->getCapturedDecl()->setNothrow();
10742  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10743  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10744  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10745  // 1.2.2 OpenMP Language Terminology
10746  // Structured block - An executable statement with a single entry at the
10747  // top and a single exit at the bottom.
10748  // The point of exit cannot be a branch out of the structured block.
10749  // longjmp() and throw() must not violate the entry/exit criteria.
10750  CS->getCapturedDecl()->setNothrow();
10751  }
10752 
10754  // In presence of clause 'collapse', it will define the nested loops number.
10755  unsigned NestedLoopCount =
10756  checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10757  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10758  VarsWithImplicitDSA, B);
10759  if (NestedLoopCount == 0)
10760  return StmtError();
10761 
10762  assert((CurContext->isDependentContext() || B.builtAll()) &&
10763  "omp loop exprs were not built");
10764 
10766 
10768  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10769 }
10770 
10772  Stmt *AStmt,
10773  SourceLocation StartLoc,
10774  SourceLocation EndLoc) {
10775  if (!AStmt)
10776  return StmtError();
10777 
10778  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10779 
10781 
10782  // OpenMP [2.7.3, single Construct, Restrictions]
10783  // The copyprivate clause must not be used with the nowait clause.
10784  const OMPClause *Nowait = nullptr;
10785  const OMPClause *Copyprivate = nullptr;
10786  for (const OMPClause *Clause : Clauses) {
10787  if (Clause->getClauseKind() == OMPC_nowait)
10788  Nowait = Clause;
10789  else if (Clause->getClauseKind() == OMPC_copyprivate)
10790  Copyprivate = Clause;
10791  if (Copyprivate && Nowait) {
10792  Diag(Copyprivate->getBeginLoc(),
10793  diag::err_omp_single_copyprivate_with_nowait);
10794  Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10795  return StmtError();
10796  }
10797  }
10798 
10799  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10800 }
10801 
10803  SourceLocation StartLoc,
10804  SourceLocation EndLoc) {
10805  if (!AStmt)
10806  return StmtError();
10807 
10809 
10810  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10811 }
10812 
10814  Stmt *AStmt,
10815  SourceLocation StartLoc,
10816  SourceLocation EndLoc) {
10817  if (!AStmt)
10818  return StmtError();
10819 
10821 
10822  return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10823 }
10824 
10826  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10827  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10828  if (!AStmt)
10829  return StmtError();
10830 
10831  bool ErrorFound = false;
10832  llvm::APSInt Hint;
10833  SourceLocation HintLoc;
10834  bool DependentHint = false;
10835  for (const OMPClause *C : Clauses) {
10836  if (C->getClauseKind() == OMPC_hint) {
10837  if (!DirName.getName()) {
10838  Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10839  ErrorFound = true;
10840  }
10841  Expr *E = cast<OMPHintClause>(C)->getHint();
10842  if (E->isTypeDependent() || E->isValueDependent() ||
10843  E->isInstantiationDependent()) {
10844  DependentHint = true;
10845  } else {
10846  Hint = E->EvaluateKnownConstInt(Context);
10847  HintLoc = C->getBeginLoc();
10848  }
10849  }
10850  }
10851  if (ErrorFound)
10852  return StmtError();
10853  const auto Pair = DSAStack->getCriticalWithHint(DirName);
10854  if (Pair.first && DirName.getName() && !DependentHint) {
10855  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10856  Diag(StartLoc, diag::err_omp_critical_with_hint);
10857  if (HintLoc.isValid())
10858  Diag(HintLoc, diag::note_omp_critical_hint_here)
10859  << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10860  else
10861  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10862  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10863  Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10864  << 1
10865  << toString(C->getHint()->EvaluateKnownConstInt(Context),
10866  /*Radix=*/10, /*Signed=*/false);
10867  } else {
10868  Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10869  }
10870  }
10871  }
10872 
10874 
10875  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10876  Clauses, AStmt);
10877  if (!Pair.first && DirName.getName() && !DependentHint)
10878  DSAStack->addCriticalWithHint(Dir, Hint);
10879  return Dir;
10880 }
10881 
10883  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10884  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10885  if (!AStmt)
10886  return StmtError();
10887 
10888  auto *CS = cast<CapturedStmt>(AStmt);
10889  // 1.2.2 OpenMP Language Terminology
10890  // Structured block - An executable statement with a single entry at the
10891  // top and a single exit at the bottom.
10892  // The point of exit cannot be a branch out of the structured block.
10893  // longjmp() and throw() must not violate the entry/exit criteria.
10894  CS->getCapturedDecl()->setNothrow();
10895 
10897  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10898  // define the nested loops number.
10899  unsigned NestedLoopCount =
10900  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10901  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10902  VarsWithImplicitDSA, B);
10903  if (NestedLoopCount == 0)
10904  return StmtError();
10905 
10906  assert((CurContext->isDependentContext() || B.builtAll()) &&
10907  "omp parallel for loop exprs were not built");
10908 
10909  if (!CurContext->isDependentContext()) {
10910  // Finalize the clauses that need pre-built expressions for CodeGen.
10911  for (OMPClause *C : Clauses) {
10912  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10913  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10914  B.NumIterations, *this, CurScope,
10915  DSAStack))
10916  return StmtError();
10917  }
10918  }
10919 
10922  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10923  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10924 }
10925 
10927  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10928  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10929  if (!AStmt)
10930  return StmtError();
10931 
10932  auto *CS = cast<CapturedStmt>(AStmt);
10933  // 1.2.2 OpenMP Language Terminology
10934  // Structured block - An executable statement with a single entry at the
10935  // top and a single exit at the bottom.
10936  // The point of exit cannot be a branch out of the structured block.
10937  // longjmp() and throw() must not violate the entry/exit criteria.
10938  CS->getCapturedDecl()->setNothrow();
10939 
10941  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10942  // define the nested loops number.
10943  unsigned NestedLoopCount =
10944  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10945  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10946  VarsWithImplicitDSA, B);
10947  if (NestedLoopCount == 0)
10948  return StmtError();
10949 
10950  if (!CurContext->isDependentContext()) {
10951  // Finalize the clauses that need pre-built expressions for CodeGen.
10952  for (OMPClause *C : Clauses) {
10953  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10954  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10955  B.NumIterations, *this, CurScope,
10956  DSAStack))
10957  return StmtError();
10958  }
10959  }
10960 
10961  if (checkSimdlenSafelenSpecified(*this, Clauses))
10962  return StmtError();
10963 
10966  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10967 }
10968 
10969 StmtResult
10971  Stmt *AStmt, SourceLocation StartLoc,
10972  SourceLocation EndLoc) {
10973  if (!AStmt)
10974  return StmtError();
10975 
10976  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10977  auto *CS = cast<CapturedStmt>(AStmt);
10978  // 1.2.2 OpenMP Language Terminology
10979  // Structured block - An executable statement with a single entry at the
10980  // top and a single exit at the bottom.
10981  // The point of exit cannot be a branch out of the structured block.
10982  // longjmp() and throw() must not violate the entry/exit criteria.
10983  CS->getCapturedDecl()->setNothrow();
10984 
10986 
10988  Context, StartLoc, EndLoc, Clauses, AStmt,
10989  DSAStack->getTaskgroupReductionRef());
10990 }
10991 
10992 StmtResult
10994  Stmt *AStmt, SourceLocation StartLoc,
10995  SourceLocation EndLoc) {
10996  if (!AStmt)
10997  return StmtError();
10998 
10999  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11000  auto *CS = cast<CapturedStmt>(AStmt);
11001  // 1.2.2 OpenMP Language Terminology
11002  // Structured block - An executable statement with a single entry at the
11003  // top and a single exit at the bottom.
11004  // The point of exit cannot be a branch out of the structured block.
11005  // longjmp() and throw() must not violate the entry/exit criteria.
11006  CS->getCapturedDecl()->setNothrow();
11007 
11009 
11011  Context, StartLoc, EndLoc, Clauses, AStmt,
11012  DSAStack->getTaskgroupReductionRef());
11013 }
11014 
11015 StmtResult
11017  Stmt *AStmt, SourceLocation StartLoc,
11018  SourceLocation EndLoc) {
11019  if (!AStmt)
11020  return StmtError();
11021 
11022  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11023  auto BaseStmt = AStmt;
11024  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11025  BaseStmt = CS->getCapturedStmt();
11026  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11027  auto S = C->children();
11028  if (S.begin() == S.end())
11029  return StmtError();
11030  // All associated statements must be '#pragma omp section' except for
11031  // the first one.
11032  for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11033  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11034  if (SectionStmt)
11035  Diag(SectionStmt->getBeginLoc(),
11036  diag::err_omp_parallel_sections_substmt_not_section);
11037  return StmtError();
11038  }
11039  cast<OMPSectionDirective>(SectionStmt)
11040  ->setHasCancel(DSAStack->isCancelRegion());
11041  }
11042  } else {
11043  Diag(AStmt->getBeginLoc(),
11044  diag::err_omp_parallel_sections_not_compound_stmt);
11045  return StmtError();
11046  }
11047 
11049 
11051  Context, StartLoc, EndLoc, Clauses, AStmt,
11052  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11053 }
11054 
11055 /// Find and diagnose mutually exclusive clause kinds.
11057  Sema &S, ArrayRef<OMPClause *> Clauses,
11058  ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11059  const OMPClause *PrevClause = nullptr;
11060  bool ErrorFound = false;
11061  for (const OMPClause *C : Clauses) {
11062  if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11063  if (!PrevClause) {
11064  PrevClause = C;
11065  } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11066  S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11067  << getOpenMPClauseName(C->getClauseKind())
11068  << getOpenMPClauseName(PrevClause->getClauseKind());
11069  S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11070  << getOpenMPClauseName(PrevClause->getClauseKind());
11071  ErrorFound = true;
11072  }
11073  }
11074  }
11075  return ErrorFound;
11076 }
11077 
11079  Stmt *AStmt, SourceLocation StartLoc,
11080  SourceLocation EndLoc) {
11081  if (!AStmt)
11082  return StmtError();
11083 
11084  // OpenMP 5.0, 2.10.1 task Construct
11085  // If a detach clause appears on the directive, then a mergeable clause cannot
11086  // appear on the same directive.
11087  if (checkMutuallyExclusiveClauses(*this, Clauses,
11088  {OMPC_detach, OMPC_mergeable}))
11089  return StmtError();
11090 
11091  auto *CS = cast<CapturedStmt>(AStmt);
11092  // 1.2.2 OpenMP Language Terminology
11093  // Structured block - An executable statement with a single entry at the
11094  // top and a single exit at the bottom.
11095  // The point of exit cannot be a branch out of the structured block.
11096  // longjmp() and throw() must not violate the entry/exit criteria.
11097  CS->getCapturedDecl()->setNothrow();
11098 
11100 
11101  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11102  DSAStack->isCancelRegion());
11103 }
11104 
11106  SourceLocation EndLoc) {
11107  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11108 }
11109 
11111  SourceLocation EndLoc) {
11112  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11113 }
11114 
11116  SourceLocation StartLoc,
11117  SourceLocation EndLoc,
11118  bool InExContext) {
11119  const OMPAtClause *AtC =
11120  OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11121 
11122  if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11123  Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11124  return StmtError();
11125  }
11126 
11127  const OMPSeverityClause *SeverityC =
11128  OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11129  const OMPMessageClause *MessageC =
11130  OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11131  Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11132 
11133  if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11134  if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11135  Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11136  << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11137  else
11138  Diag(StartLoc, diag::err_diagnose_if_succeeded)
11139  << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11140  if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11141  return StmtError();
11142  }
11143  return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11144 }
11145 
11147  SourceLocation StartLoc,
11148  SourceLocation EndLoc) {
11149  const OMPNowaitClause *NowaitC =
11150  OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11151  bool HasDependC =
11152  !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11153  .empty();
11154  if (NowaitC && !HasDependC) {
11155  Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11156  return StmtError();
11157  }
11158 
11159  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11160 }
11161 
11163  Stmt *AStmt,
11164  SourceLocation StartLoc,
11165  SourceLocation EndLoc) {
11166  if (!AStmt)
11167  return StmtError();
11168 
11169  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11170 
11172 
11173  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11174  AStmt,
11175  DSAStack->getTaskgroupReductionRef());
11176 }
11177 
11179  SourceLocation StartLoc,
11180  SourceLocation EndLoc) {
11181  OMPFlushClause *FC = nullptr;
11182  OMPClause *OrderClause = nullptr;
11183  for (OMPClause *C : Clauses) {
11184  if (C->getClauseKind() == OMPC_flush)
11185  FC = cast<OMPFlushClause>(C);
11186  else
11187  OrderClause = C;
11188  }
11189  OpenMPClauseKind MemOrderKind = OMPC_unknown;
11190  SourceLocation MemOrderLoc;
11191  for (const OMPClause *C : Clauses) {
11192  if (C->getClauseKind() == OMPC_acq_rel ||
11193  C->getClauseKind() == OMPC_acquire ||
11194  C->getClauseKind() == OMPC_release) {
11195  if (MemOrderKind != OMPC_unknown) {
11196  Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11197  << getOpenMPDirectiveName(OMPD_flush) << 1
11198  << SourceRange(C->getBeginLoc(), C->getEndLoc());
11199  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11200  << getOpenMPClauseName(MemOrderKind);
11201  } else {
11202  MemOrderKind = C->getClauseKind();
11203  MemOrderLoc = C->getBeginLoc();
11204  }
11205  }
11206  }
11207  if (FC && OrderClause) {
11208  Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11209  << getOpenMPClauseName(OrderClause->getClauseKind());
11210  Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11211  << getOpenMPClauseName(OrderClause->getClauseKind());
11212  return StmtError();
11213  }
11214  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11215 }
11216 
11218  SourceLocation StartLoc,
11219  SourceLocation EndLoc) {
11220  if (Clauses.empty()) {
11221  Diag(StartLoc, diag::err_omp_depobj_expected);
11222  return StmtError();
11223  } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11224  Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11225  return StmtError();
11226  }
11227  // Only depobj expression and another single clause is allowed.
11228  if (Clauses.size() > 2) {
11229  Diag(Clauses[2]->getBeginLoc(),
11230  diag::err_omp_depobj_single_clause_expected);
11231  return StmtError();
11232  } else if (Clauses.size() < 1) {
11233  Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11234  return StmtError();
11235  }
11236  return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11237 }
11238 
11240  SourceLocation StartLoc,
11241  SourceLocation EndLoc) {
11242  // Check that exactly one clause is specified.
11243  if (Clauses.size() != 1) {
11244  Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11245  diag::err_omp_scan_single_clause_expected);
11246  return StmtError();
11247  }
11248  // Check that scan directive is used in the scopeof the OpenMP loop body.
11249  if (Scope *S = DSAStack->getCurScope()) {
11250  Scope *ParentS = S->getParent();
11251  if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11252  !ParentS->getBreakParent()->isOpenMPLoopScope())
11253  return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11254  << getOpenMPDirectiveName(OMPD_scan) << 5);
11255  }
11256  // Check that only one instance of scan directives is used in the same outer
11257  // region.
11258  if (DSAStack->doesParentHasScanDirective()) {
11259  Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11260  Diag(DSAStack->getParentScanDirectiveLoc(),
11261  diag::note_omp_previous_directive)
11262  << "scan";
11263  return StmtError();
11264  }
11265  DSAStack->setParentHasScanDirective(StartLoc);
11266  return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11267 }
11268 
11270  Stmt *AStmt,
11271  SourceLocation StartLoc,
11272  SourceLocation EndLoc) {
11273  const OMPClause *DependFound = nullptr;
11274  const OMPClause *DependSourceClause = nullptr;
11275  const OMPClause *DependSinkClause = nullptr;
11276  bool ErrorFound = false;
11277  const OMPThreadsClause *TC = nullptr;
11278  const OMPSIMDClause *SC = nullptr;
11279  for (const OMPClause *C : Clauses) {
11280  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
11281  DependFound = C;
11282  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
11283  if (DependSourceClause) {
11284  Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11285  << getOpenMPDirectiveName(OMPD_ordered)
11286  << getOpenMPClauseName(OMPC_depend) << 2;
11287  ErrorFound = true;
11288  } else {
11289  DependSourceClause = C;
11290  }
11291  if (DependSinkClause) {
11292  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11293  << 0;
11294  ErrorFound = true;
11295  }
11296  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
11297  if (DependSourceClause) {
11298  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11299  << 1;
11300  ErrorFound = true;
11301  }
11302  DependSinkClause = C;
11303  }
11304  } else if (C->getClauseKind() == OMPC_threads) {
11305  TC = cast<OMPThreadsClause>(C);
11306  } else if (C->getClauseKind() == OMPC_simd) {
11307  SC = cast<OMPSIMDClause>(C);
11308  }
11309  }
11310  if (!ErrorFound && !SC &&
11311  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11312  // OpenMP [2.8.1,simd Construct, Restrictions]
11313  // An ordered construct with the simd clause is the only OpenMP construct
11314  // that can appear in the simd region.
11315  Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11316  << (LangOpts.OpenMP >= 50 ? 1 : 0);
11317  ErrorFound = true;
11318  } else if (DependFound && (TC || SC)) {
11319  Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
11320  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11321  ErrorFound = true;
11322  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
11323  Diag(DependFound->getBeginLoc(),
11324  diag::err_omp_ordered_directive_without_param);
11325  ErrorFound = true;
11326  } else if (TC || Clauses.empty()) {
11327  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11328  SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11329  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11330  << (TC != nullptr);
11331  Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11332  ErrorFound = true;
11333  }
11334  }
11335  if ((!AStmt && !DependFound) || ErrorFound)
11336  return StmtError();
11337 
11338  // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11339  // During execution of an iteration of a worksharing-loop or a loop nest
11340  // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11341  // must not execute more than one ordered region corresponding to an ordered
11342  // construct without a depend clause.
11343  if (!DependFound) {
11344  if (DSAStack->doesParentHasOrderedDirective()) {
11345  Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11346  Diag(DSAStack->getParentOrderedDirectiveLoc(),
11347  diag::note_omp_previous_directive)
11348  << "ordered";
11349  return StmtError();
11350  }
11351  DSAStack->setParentHasOrderedDirective(StartLoc);
11352  }
11353 
11354  if (AStmt) {
11355  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11356 
11358  }
11359 
11360  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11361 }
11362 
11363 namespace {
11364 /// Helper class for checking expression in 'omp atomic [update]'
11365 /// construct.
11366 class OpenMPAtomicUpdateChecker {
11367  /// Error results for atomic update expressions.
11368  enum ExprAnalysisErrorCode {
11369  /// A statement is not an expression statement.
11370  NotAnExpression,
11371  /// Expression is not builtin binary or unary operation.
11372  NotABinaryOrUnaryExpression,
11373  /// Unary operation is not post-/pre- increment/decrement operation.
11374  NotAnUnaryIncDecExpression,
11375  /// An expression is not of scalar type.
11376  NotAScalarType,
11377  /// A binary operation is not an assignment operation.
11378  NotAnAssignmentOp,
11379  /// RHS part of the binary operation is not a binary expression.
11380  NotABinaryExpression,
11381  /// RHS part is not additive/multiplicative/shift/biwise binary
11382  /// expression.
11383  NotABinaryOperator,
11384  /// RHS binary operation does not have reference to the updated LHS
11385  /// part.
11386  NotAnUpdateExpression,
11387  /// No errors is found.
11388  NoError
11389  };
11390  /// Reference to Sema.
11391  Sema &SemaRef;
11392  /// A location for note diagnostics (when error is found).
11393  SourceLocation NoteLoc;
11394  /// 'x' lvalue part of the source atomic expression.
11395  Expr *X;
11396  /// 'expr' rvalue part of the source atomic expression.
11397  Expr *E;
11398  /// Helper expression of the form
11399  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11400  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11401  Expr *UpdateExpr;
11402  /// Is 'x' a LHS in a RHS part of full update expression. It is
11403  /// important for non-associative operations.
11404  bool IsXLHSInRHSPart;
11405  BinaryOperatorKind Op;
11406  SourceLocation OpLoc;
11407  /// true if the source expression is a postfix unary operation, false
11408  /// if it is a prefix unary operation.
11409  bool IsPostfixUpdate;
11410 
11411 public:
11412  OpenMPAtomicUpdateChecker(Sema &SemaRef)
11413  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11414  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11415  /// Check specified statement that it is suitable for 'atomic update'
11416  /// constructs and extract 'x', 'expr' and Operation from the original
11417  /// expression. If DiagId and NoteId == 0, then only check is performed
11418  /// without error notification.
11419  /// \param DiagId Diagnostic which should be emitted if error is found.
11420  /// \param NoteId Diagnostic note for the main error message.
11421  /// \return true if statement is not an update expression, false otherwise.
11422  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11423  /// Return the 'x' lvalue part of the source atomic expression.
11424  Expr *getX() const { return X; }
11425  /// Return the 'expr' rvalue part of the source atomic expression.
11426  Expr *getExpr() const { return E; }
11427  /// Return the update expression used in calculation of the updated
11428  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11429  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11430  Expr *getUpdateExpr() const { return UpdateExpr; }
11431  /// Return true if 'x' is LHS in RHS part of full update expression,
11432  /// false otherwise.
11433  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11434 
11435  /// true if the source expression is a postfix unary operation, false
11436  /// if it is a prefix unary operation.
11437  bool isPostfixUpdate() const { return IsPostfixUpdate; }
11438 
11439 private:
11440  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11441  unsigned NoteId = 0);
11442 };
11443 
11444 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11445  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11446  ExprAnalysisErrorCode ErrorFound = NoError;
11447  SourceLocation ErrorLoc, NoteLoc;
11448  SourceRange ErrorRange, NoteRange;
11449  // Allowed constructs are:
11450  // x = x binop expr;
11451  // x = expr binop x;
11452  if (AtomicBinOp->getOpcode() == BO_Assign) {
11453  X = AtomicBinOp->getLHS();
11454  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11455  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11456  if (AtomicInnerBinOp->isMultiplicativeOp() ||
11457  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11458  AtomicInnerBinOp->isBitwiseOp()) {
11459  Op = AtomicInnerBinOp->getOpcode();
11460  OpLoc = AtomicInnerBinOp->getOperatorLoc();
11461  Expr *LHS = AtomicInnerBinOp->getLHS();
11462  Expr *RHS = AtomicInnerBinOp->getRHS();
11463  llvm::FoldingSetNodeID XId, LHSId, RHSId;
11464  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11465  /*Canonical=*/true);
11466  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11467  /*Canonical=*/true);
11468  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11469  /*Canonical=*/true);
11470  if (XId == LHSId) {
11471  E = RHS;
11472  IsXLHSInRHSPart = true;
11473  } else if (XId == RHSId) {
11474  E = LHS;
11475  IsXLHSInRHSPart = false;
11476  } else {
11477  ErrorLoc = AtomicInnerBinOp->getExprLoc();
11478  ErrorRange = AtomicInnerBinOp->getSourceRange();
11479  NoteLoc = X->getExprLoc();
11480  NoteRange = X->getSourceRange();
11481  ErrorFound = NotAnUpdateExpression;
11482  }
11483  } else {
11484  ErrorLoc = AtomicInnerBinOp->getExprLoc();
11485  ErrorRange = AtomicInnerBinOp->getSourceRange();
11486  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11487  NoteRange = SourceRange(NoteLoc, NoteLoc);
11488  ErrorFound = NotABinaryOperator;
11489  }
11490  } else {
11491  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11492  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11493  ErrorFound = NotABinaryExpression;
11494  }
11495  } else {
11496  ErrorLoc = AtomicBinOp->getExprLoc();
11497  ErrorRange = AtomicBinOp->getSourceRange();
11498  NoteLoc = AtomicBinOp->getOperatorLoc();
11499  NoteRange = SourceRange(NoteLoc, NoteLoc);
11500  ErrorFound = NotAnAssignmentOp;
11501  }
11502  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11503  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11504  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11505  return true;
11506  }
11507  if (SemaRef.CurContext->isDependentContext())
11508  E = X = UpdateExpr = nullptr;
11509  return ErrorFound != NoError;
11510 }
11511 
11512 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11513  unsigned NoteId) {
11514  ExprAnalysisErrorCode ErrorFound = NoError;
11515  SourceLocation ErrorLoc, NoteLoc;
11516  SourceRange ErrorRange, NoteRange;
11517  // Allowed constructs are:
11518  // x++;
11519  // x--;
11520  // ++x;
11521  // --x;
11522  // x binop= expr;
11523  // x = x binop expr;
11524  // x = expr binop x;
11525  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11526  AtomicBody = AtomicBody->IgnoreParenImpCasts();
11527  if (AtomicBody->getType()->isScalarType() ||
11528  AtomicBody->isInstantiationDependent()) {
11529  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11530  AtomicBody->IgnoreParenImpCasts())) {
11531  // Check for Compound Assignment Operation
11533  AtomicCompAssignOp->getOpcode());
11534  OpLoc = AtomicCompAssignOp->getOperatorLoc();
11535  E = AtomicCompAssignOp->getRHS();
11536  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11537  IsXLHSInRHSPart = true;
11538  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11539  AtomicBody->IgnoreParenImpCasts())) {
11540  // Check for Binary Operation
11541  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11542  return true;
11543  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11544  AtomicBody->IgnoreParenImpCasts())) {
11545  // Check for Unary Operation
11546  if (AtomicUnaryOp->isIncrementDecrementOp()) {
11547  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11548  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11549  OpLoc = AtomicUnaryOp->getOperatorLoc();
11550  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11551  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11552  IsXLHSInRHSPart = true;
11553  } else {
11554  ErrorFound = NotAnUnaryIncDecExpression;
11555  ErrorLoc = AtomicUnaryOp->getExprLoc();
11556  ErrorRange = AtomicUnaryOp->getSourceRange();
11557  NoteLoc = AtomicUnaryOp->getOperatorLoc();
11558  NoteRange = SourceRange(NoteLoc, NoteLoc);
11559  }
11560  } else if (!AtomicBody->isInstantiationDependent()) {
11561  ErrorFound = NotABinaryOrUnaryExpression;
11562  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11563  NoteRange = ErrorRange = AtomicBody->getSourceRange();
11564  }
11565  } else {
11566  ErrorFound = NotAScalarType;
11567  NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11568  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11569  }
11570  } else {
11571  ErrorFound = NotAnExpression;
11572  NoteLoc = ErrorLoc = S->getBeginLoc();
11573  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11574  }
11575  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11576  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11577  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11578  return true;
11579  }
11580  if (SemaRef.CurContext->isDependentContext())
11581  E = X = UpdateExpr = nullptr;
11582  if (ErrorFound == NoError && E && X) {
11583  // Build an update expression of form 'OpaqueValueExpr(x) binop
11584  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11585  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11586  auto *OVEX = new (SemaRef.getASTContext())
11587  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11588  auto *OVEExpr = new (SemaRef.getASTContext())
11590  ExprResult Update =
11591  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11592  IsXLHSInRHSPart ? OVEExpr : OVEX);
11593  if (Update.isInvalid())
11594  return true;
11595  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11597  if (Update.isInvalid())
11598  return true;
11599  UpdateExpr = Update.get();
11600  }
11601  return ErrorFound != NoError;
11602 }
11603 
11604 /// Get the node id of the fixed point of an expression \a S.
11605 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11606  llvm::FoldingSetNodeID Id;
11607  S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11608  return Id;
11609 }
11610 
11611 /// Check if two expressions are same.
11612 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11613  const Expr *RHS) {
11614  return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11615 }
11616 
11617 class OpenMPAtomicCompareChecker {
11618 public:
11619  /// All kinds of errors that can occur in `atomic compare`
11620  enum ErrorTy {
11621  /// Empty compound statement.
11622  NoStmt = 0,
11623  /// More than one statement in a compound statement.
11624  MoreThanOneStmt,
11625  /// Not an assignment binary operator.
11626  NotAnAssignment,
11627  /// Not a conditional operator.
11628  NotCondOp,
11629  /// Wrong false expr. According to the spec, 'x' should be at the false
11630  /// expression of a conditional expression.
11631  WrongFalseExpr,
11632  /// The condition of a conditional expression is not a binary operator.
11633  NotABinaryOp,
11634  /// Invalid binary operator (not <, >, or ==).
11635  InvalidBinaryOp,
11636  /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11637  InvalidComparison,
11638  /// X is not a lvalue.
11639  XNotLValue,
11640  /// Not a scalar.
11641  NotScalar,
11642  /// Not an integer.
11643  NotInteger,
11644  /// 'else' statement is not expected.
11645  UnexpectedElse,
11646  /// Not an equality operator.
11647  NotEQ,
11648  /// Invalid assignment (not v == x).
11649  InvalidAssignment,
11650  /// Not if statement
11651  NotIfStmt,
11652  /// More than two statements in a compund statement.
11653  MoreThanTwoStmts,
11654  /// Not a compound statement.
11655  NotCompoundStmt,
11656  /// No else statement.
11657  NoElse,
11658  /// Not 'if (r)'.
11659  InvalidCondition,
11660  /// No error.
11661  NoError,
11662  };
11663 
11664  struct ErrorInfoTy {
11665  ErrorTy Error;
11666  SourceLocation ErrorLoc;
11667  SourceRange ErrorRange;
11668  SourceLocation NoteLoc;
11669  SourceRange NoteRange;
11670  };
11671 
11672  OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11673 
11674  /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11675  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11676 
11677  Expr *getX() const { return X; }
11678  Expr *getE() const { return E; }
11679  Expr *getD() const { return D; }
11680  Expr *getCond() const { return C; }
11681  bool isXBinopExpr() const { return IsXBinopExpr; }
11682 
11683 protected:
11684  /// Reference to ASTContext
11685  ASTContext &ContextRef;
11686  /// 'x' lvalue part of the source atomic expression.
11687  Expr *X = nullptr;
11688  /// 'expr' or 'e' rvalue part of the source atomic expression.
11689  Expr *E = nullptr;
11690  /// 'd' rvalue part of the source atomic expression.
11691  Expr *D = nullptr;
11692  /// 'cond' part of the source atomic expression. It is in one of the following
11693  /// forms:
11694  /// expr ordop x
11695  /// x ordop expr
11696  /// x == e
11697  /// e == x
11698  Expr *C = nullptr;
11699  /// True if the cond expr is in the form of 'x ordop expr'.
11700  bool IsXBinopExpr = true;
11701 
11702  /// Check if it is a valid conditional update statement (cond-update-stmt).
11703  bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11704 
11705  /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11706  bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11707 
11708  /// Check if all captured values have right type.
11709  bool checkType(ErrorInfoTy &ErrorInfo) const;
11710 
11711  static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11712  bool ShouldBeLValue, bool ShouldBeInteger = false) {
11713  if (E->isInstantiationDependent())
11714  return true;
11715 
11716  if (ShouldBeLValue && !E->isLValue()) {
11717  ErrorInfo.Error = ErrorTy::XNotLValue;
11718  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11719  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11720  return false;
11721  }
11722 
11723  QualType QTy = E->getType();
11724  if (!QTy->isScalarType()) {
11725  ErrorInfo.Error = ErrorTy::NotScalar;
11726  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11727  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11728  return false;
11729  }
11730  if (ShouldBeInteger && !QTy->isIntegerType()) {
11731  ErrorInfo.Error = ErrorTy::NotInteger;
11732  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11733  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11734  return false;
11735  }
11736 
11737  return true;
11738  }
11739  };
11740 
11741 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11742  ErrorInfoTy &ErrorInfo) {
11743  auto *Then = S->getThen();
11744  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11745  if (CS->body_empty()) {
11746  ErrorInfo.Error = ErrorTy::NoStmt;
11747  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11748  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11749  return false;
11750  }
11751  if (CS->size() > 1) {
11752  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11753  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11754  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11755  return false;
11756  }
11757  Then = CS->body_front();
11758  }
11759 
11760  auto *BO = dyn_cast<BinaryOperator>(Then);
11761  if (!BO) {
11762  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11763  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11764  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11765  return false;
11766  }
11767  if (BO->getOpcode() != BO_Assign) {
11768  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11769  ErrorInfo.ErrorLoc = BO->getExprLoc();
11770  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11771  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11772  return false;
11773  }
11774 
11775  X = BO->getLHS();
11776 
11777  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11778  if (!Cond) {
11779  ErrorInfo.Error = ErrorTy::NotABinaryOp;
11780  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11781  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11782  return false;
11783  }
11784 
11785  switch (Cond->getOpcode()) {
11786  case BO_EQ: {
11787  C = Cond;
11788  D = BO->getRHS();
11789  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11790  E = Cond->getRHS();
11791  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11792  E = Cond->getLHS();
11793  } else {
11794  ErrorInfo.Error = ErrorTy::InvalidComparison;
11795  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11796  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11797  return false;
11798  }
11799  break;
11800  }
11801  case BO_LT:
11802  case BO_GT: {
11803  E = BO->getRHS();
11804  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11805  checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11806  C = Cond;
11807  } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11808  checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11809  C = Cond;
11810  IsXBinopExpr = false;
11811  } else {
11812  ErrorInfo.Error = ErrorTy::InvalidComparison;
11813  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11814  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11815  return false;
11816  }
11817  break;
11818  }
11819  default:
11820  ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11821  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11822  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11823  return false;
11824  }
11825 
11826  if (S->getElse()) {
11827  ErrorInfo.Error = ErrorTy::UnexpectedElse;
11828  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11829  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11830  return false;
11831  }
11832 
11833  return true;
11834 }
11835 
11836 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11837  ErrorInfoTy &ErrorInfo) {
11838  auto *BO = dyn_cast<BinaryOperator>(S);
11839  if (!BO) {
11840  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11841  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11842  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11843  return false;
11844  }
11845  if (BO->getOpcode() != BO_Assign) {
11846  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11847  ErrorInfo.ErrorLoc = BO->getExprLoc();
11848  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11849  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11850  return false;
11851  }
11852 
11853  X = BO->getLHS();
11854 
11855  auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11856  if (!CO) {
11857  ErrorInfo.Error = ErrorTy::NotCondOp;
11858  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11859  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11860  return false;
11861  }
11862 
11863  if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11864  ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11865  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11866  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11867  CO->getFalseExpr()->getSourceRange();
11868  return false;
11869  }
11870 
11871  auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11872  if (!Cond) {
11873  ErrorInfo.Error = ErrorTy::NotABinaryOp;
11874  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11875  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11876  CO->getCond()->getSourceRange();
11877  return false;
11878  }
11879 
11880  switch (Cond->getOpcode()) {
11881  case BO_EQ: {
11882  C = Cond;
11883  D = CO->getTrueExpr();
11884  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11885  E = Cond->getRHS();
11886  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11887  E = Cond->getLHS();
11888  } else {
11889  ErrorInfo.Error = ErrorTy::InvalidComparison;
11890  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11891  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11892  return false;
11893  }
11894  break;
11895  }
11896  case BO_LT:
11897  case BO_GT: {
11898  E = CO->getTrueExpr();
11899  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11900  checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11901  C = Cond;
11902  } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11903  checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11904  C = Cond;
11905  IsXBinopExpr = false;
11906  } else {
11907  ErrorInfo.Error = ErrorTy::InvalidComparison;
11908  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11909  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11910  return false;
11911  }
11912  break;
11913  }
11914  default:
11915  ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11916  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11917  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11918  return false;
11919  }
11920 
11921  return true;
11922 }
11923 
11924 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11925  // 'x' and 'e' cannot be nullptr
11926  assert(X && E && "X and E cannot be nullptr");
11927 
11928  if (!CheckValue(X, ErrorInfo, true))
11929  return false;
11930 
11931  if (!CheckValue(E, ErrorInfo, false))
11932  return false;
11933 
11934  if (D && !CheckValue(D, ErrorInfo, false))
11935  return false;
11936 
11937  return true;
11938 }
11939 
11940 bool OpenMPAtomicCompareChecker::checkStmt(
11941  Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11942  auto *CS = dyn_cast<CompoundStmt>(S);
11943  if (CS) {
11944  if (CS->body_empty()) {
11945  ErrorInfo.Error = ErrorTy::NoStmt;
11946  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11947  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11948  return false;
11949  }
11950 
11951  if (CS->size() != 1) {
11952  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11953  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11954  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11955  return false;
11956  }
11957  S = CS->body_front();
11958  }
11959 
11960  auto Res = false;
11961 
11962  if (auto *IS = dyn_cast<IfStmt>(S)) {
11963  // Check if the statement is in one of the following forms
11964  // (cond-update-stmt):
11965  // if (expr ordop x) { x = expr; }
11966  // if (x ordop expr) { x = expr; }
11967  // if (x == e) { x = d; }
11968  Res = checkCondUpdateStmt(IS, ErrorInfo);
11969  } else {
11970  // Check if the statement is in one of the following forms (cond-expr-stmt):
11971  // x = expr ordop x ? expr : x;
11972  // x = x ordop expr ? expr : x;
11973  // x = x == e ? d : x;
11974  Res = checkCondExprStmt(S, ErrorInfo);
11975  }
11976 
11977  if (!Res)
11978  return false;
11979 
11980  return checkType(ErrorInfo);
11981 }
11982 
11983 class OpenMPAtomicCompareCaptureChecker final
11984  : public OpenMPAtomicCompareChecker {
11985 public:
11986  OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11987 
11988  Expr *getV() const { return V; }
11989  Expr *getR() const { return R; }
11990  bool isFailOnly() const { return IsFailOnly; }
11991  bool isPostfixUpdate() const { return IsPostfixUpdate; }
11992 
11993  /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11994  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11995 
11996 private:
11997  bool checkType(ErrorInfoTy &ErrorInfo);
11998 
11999  // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12000  // form of 'conditional-update-capture-atomic' structured block on the v5.2
12001  // spec p.p. 82:
12002  // (1) { v = x; cond-update-stmt }
12003  // (2) { cond-update-stmt v = x; }
12004  // (3) if(x == e) { x = d; } else { v = x; }
12005  // (4) { r = x == e; if(r) { x = d; } }
12006  // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12007 
12008  /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12009  bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12010 
12011  /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12012  /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12013  bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12014 
12015  /// 'v' lvalue part of the source atomic expression.
12016  Expr *V = nullptr;
12017  /// 'r' lvalue part of the source atomic expression.
12018  Expr *R = nullptr;
12019  /// If 'v' is only updated when the comparison fails.
12020  bool IsFailOnly = false;
12021  /// If original value of 'x' must be stored in 'v', not an updated one.
12022  bool IsPostfixUpdate = false;
12023 };
12024 
12025 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12026  if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12027  return false;
12028 
12029  if (V && !CheckValue(V, ErrorInfo, true))
12030  return false;
12031 
12032  if (R && !CheckValue(R, ErrorInfo, true, true))
12033  return false;
12034 
12035  return true;
12036 }
12037 
12038 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12039  ErrorInfoTy &ErrorInfo) {
12040  IsFailOnly = true;
12041 
12042  auto *Then = S->getThen();
12043  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12044  if (CS->body_empty()) {
12045  ErrorInfo.Error = ErrorTy::NoStmt;
12046  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12047  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12048  return false;
12049  }
12050  if (CS->size() > 1) {
12051  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12052  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12053  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12054  return false;
12055  }
12056  Then = CS->body_front();
12057  }
12058 
12059  auto *BO = dyn_cast<BinaryOperator>(Then);
12060  if (!BO) {
12061  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12062  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12063  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12064  return false;
12065  }
12066  if (BO->getOpcode() != BO_Assign) {
12067  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12068  ErrorInfo.ErrorLoc = BO->getExprLoc();
12069  ErrorInfo.NoteLoc = BO->getOperatorLoc();
12070  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12071  return false;
12072  }
12073 
12074  X = BO->getLHS();
12075  D = BO->getRHS();
12076 
12077  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12078  if (!Cond) {
12079  ErrorInfo.Error = ErrorTy::NotABinaryOp;
12080  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12081  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12082  return false;
12083  }
12084  if (Cond->getOpcode() != BO_EQ) {
12085  ErrorInfo.Error = ErrorTy::NotEQ;
12086  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12087  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12088  return false;
12089  }
12090 
12091  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12092  E = Cond->getRHS();
12093  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12094  E = Cond->getLHS();
12095  } else {
12096  ErrorInfo.Error = ErrorTy::InvalidComparison;
12097  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12098  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12099  return false;
12100  }
12101 
12102  C = Cond;
12103 
12104  if (!S->getElse()) {
12105  ErrorInfo.Error = ErrorTy::NoElse;
12106  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12107  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12108  return false;
12109  }
12110 
12111  auto *Else = S->getElse();
12112  if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12113  if (CS->body_empty()) {
12114  ErrorInfo.Error = ErrorTy::NoStmt;
12115  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12116  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12117  return false;
12118  }
12119  if (CS->size() > 1) {
12120  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12121  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12122  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12123  return false;
12124  }
12125  Else = CS->body_front();
12126  }
12127 
12128  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12129  if (!ElseBO) {
12130  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12131  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12132  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12133  return false;
12134  }
12135  if (ElseBO->getOpcode() != BO_Assign) {
12136  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12137  ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12138  ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12139  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12140  return false;
12141  }
12142 
12143  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12144  ErrorInfo.Error = ErrorTy::InvalidAssignment;
12145  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12146  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12147  ElseBO->getRHS()->getSourceRange();
12148  return false;
12149  }
12150 
12151  V = ElseBO->getLHS();
12152 
12153  return checkType(ErrorInfo);
12154 }
12155 
12156 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12157  ErrorInfoTy &ErrorInfo) {
12158  // We don't check here as they should be already done before call this
12159  // function.
12160  auto *CS = cast<CompoundStmt>(S);
12161  assert(CS->size() == 2 && "CompoundStmt size is not expected");
12162  auto *S1 = cast<BinaryOperator>(CS->body_front());
12163  auto *S2 = cast<IfStmt>(CS->body_back());
12164  assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12165 
12166  if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12167  ErrorInfo.Error = ErrorTy::InvalidCondition;
12168  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12169  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12170  return false;
12171  }
12172 
12173  R = S1->getLHS();
12174 
12175  auto *Then = S2->getThen();
12176  if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12177  if (ThenCS->body_empty()) {
12178  ErrorInfo.Error = ErrorTy::NoStmt;
12179  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12180  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12181  return false;
12182  }
12183  if (ThenCS->size() > 1) {
12184  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12185  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12186  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12187  return false;
12188  }
12189  Then = ThenCS->body_front();
12190  }
12191 
12192  auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12193  if (!ThenBO) {
12194  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12195  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12196  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12197  return false;
12198  }
12199  if (ThenBO->getOpcode() != BO_Assign) {
12200  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12201  ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12202  ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12203  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12204  return false;
12205  }
12206 
12207  X = ThenBO->getLHS();
12208  D = ThenBO->getRHS();
12209 
12210  auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12211  if (BO->getOpcode() != BO_EQ) {
12212  ErrorInfo.Error = ErrorTy::NotEQ;
12213  ErrorInfo.ErrorLoc = BO->getExprLoc();
12214  ErrorInfo.NoteLoc = BO->getOperatorLoc();
12215  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12216  return false;
12217  }
12218 
12219  C = BO;
12220 
12221  if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12222  E = BO->getRHS();
12223  } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12224  E = BO->getLHS();
12225  } else {
12226  ErrorInfo.Error = ErrorTy::InvalidComparison;
12227  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12228  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12229  return false;
12230  }
12231 
12232  if (S2->getElse()) {
12233  IsFailOnly = true;
12234 
12235  auto *Else = S2->getElse();
12236  if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12237  if (ElseCS->body_empty()) {
12238  ErrorInfo.Error = ErrorTy::NoStmt;
12239  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12240  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12241  return false;
12242  }
12243  if (ElseCS->size() > 1) {
12244  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12245  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12246  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12247  return false;
12248  }
12249  Else = ElseCS->body_front();
12250  }
12251 
12252  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12253  if (!ElseBO) {
12254  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12255  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12256  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12257  return false;
12258  }
12259  if (ElseBO->getOpcode() != BO_Assign) {
12260  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12261  ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12262  ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12263  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12264  return false;
12265  }
12266  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12267  ErrorInfo.Error = ErrorTy::InvalidAssignment;
12268  ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12269  ErrorInfo.NoteLoc = X->getExprLoc();
12270  ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12271  ErrorInfo.NoteRange = X->getSourceRange();
12272  return false;
12273  }
12274 
12275  V = ElseBO->getLHS();
12276  }
12277 
12278  return checkType(ErrorInfo);
12279 }
12280 
12281 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12282  ErrorInfoTy &ErrorInfo) {
12283  // if(x == e) { x = d; } else { v = x; }
12284  if (auto *IS = dyn_cast<IfStmt>(S))
12285  return checkForm3(IS, ErrorInfo);
12286 
12287  auto *CS = dyn_cast<CompoundStmt>(S);
12288  if (!CS) {
12289  ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12290  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12291  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12292  return false;
12293  }
12294  if (CS->body_empty()) {
12295  ErrorInfo.Error = ErrorTy::NoStmt;
12296  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12297  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12298  return false;
12299  }
12300 
12301  // { if(x == e) { x = d; } else { v = x; } }
12302  if (CS->size() == 1) {
12303  auto *IS = dyn_cast<IfStmt>(CS->body_front());
12304  if (!IS) {
12305  ErrorInfo.Error = ErrorTy::NotIfStmt;
12306  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12307  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12308  CS->body_front()->getSourceRange();
12309  return false;
12310  }
12311 
12312  return checkForm3(IS, ErrorInfo);
12313  } else if (CS->size() == 2) {
12314  auto *S1 = CS->body_front();
12315  auto *S2 = CS->body_back();
12316 
12317  Stmt *UpdateStmt = nullptr;
12318  Stmt *CondUpdateStmt = nullptr;
12319  Stmt *CondExprStmt = nullptr;
12320 
12321  if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12322  // It could be one of the following cases:
12323  // { v = x; cond-update-stmt }
12324  // { v = x; cond-expr-stmt }
12325  // { cond-expr-stmt; v = x; }
12326  // form 45
12327  if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12328  isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12329  // check if form 45
12330  if (isa<IfStmt>(S2))
12331  return checkForm45(CS, ErrorInfo);
12332  // { cond-expr-stmt; v = x; }
12333  CondExprStmt = S1;
12334  UpdateStmt = S2;
12335  } else {
12336  IsPostfixUpdate = true;
12337  UpdateStmt = S1;
12338  if (isa<IfStmt>(S2)) {
12339  // { v = x; cond-update-stmt }
12340  CondUpdateStmt = S2;
12341  } else {
12342  // { v = x; cond-expr-stmt }
12343  CondExprStmt = S2;
12344  }
12345  }
12346  } else {
12347  // { cond-update-stmt v = x; }
12348  UpdateStmt = S2;
12349  CondUpdateStmt = S1;
12350  }
12351 
12352  auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12353  auto *IS = dyn_cast<IfStmt>(CUS);
12354  if (!IS) {
12355  ErrorInfo.Error = ErrorTy::NotIfStmt;
12356  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12357  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12358  return false;
12359  }
12360 
12361  return checkCondUpdateStmt(IS, ErrorInfo);
12362  };
12363 
12364  // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12365  auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12366  auto *BO = dyn_cast<BinaryOperator>(US);
12367  if (!BO) {
12368  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12369  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12370  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12371  return false;
12372  }
12373  if (BO->getOpcode() != BO_Assign) {
12374  ErrorInfo.Error = ErrorTy::NotAnAssignment;
12375  ErrorInfo.ErrorLoc = BO->getExprLoc();
12376  ErrorInfo.NoteLoc = BO->getOperatorLoc();
12377  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12378  return false;
12379  }
12380  if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12381  ErrorInfo.Error = ErrorTy::InvalidAssignment;
12382  ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12383  ErrorInfo.NoteLoc = this->X->getExprLoc();
12384  ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12385  ErrorInfo.NoteRange = this->X->getSourceRange();
12386  return false;
12387  }
12388 
12389  this->V = BO->getLHS();
12390 
12391  return true;
12392  };
12393 
12394  if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12395  return false;
12396  if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12397  return false;
12398  if (!CheckUpdateStmt(UpdateStmt))
12399  return false;
12400  } else {
12401  ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12402  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12403  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12404  return false;
12405  }
12406 
12407  return checkType(ErrorInfo);
12408 }
12409 } // namespace
12410 
12412  Stmt *AStmt,
12413  SourceLocation StartLoc,
12414  SourceLocation EndLoc) {
12415  // Register location of the first atomic directive.
12416  DSAStack->addAtomicDirectiveLoc(StartLoc);
12417  if (!AStmt)
12418  return StmtError();
12419 
12420  // 1.2.2 OpenMP Language Terminology
12421  // Structured block - An executable statement with a single entry at the
12422  // top and a single exit at the bottom.
12423  // The point of exit cannot be a branch out of the structured block.
12424  // longjmp() and throw() must not violate the entry/exit criteria.
12425  OpenMPClauseKind AtomicKind = OMPC_unknown;
12426  SourceLocation AtomicKindLoc;
12427  OpenMPClauseKind MemOrderKind = OMPC_unknown;
12428  SourceLocation MemOrderLoc;
12429  bool MutexClauseEncountered = false;
12430  llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12431  for (const OMPClause *C : Clauses) {
12432  switch (C->getClauseKind()) {
12433  case OMPC_read:
12434  case OMPC_write:
12435  case OMPC_update:
12436  MutexClauseEncountered = true;
12437  [[fallthrough]];
12438  case OMPC_capture:
12439  case OMPC_compare: {
12440  if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12441  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12442  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12443  Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12444  << getOpenMPClauseName(AtomicKind);
12445  } else {
12446  AtomicKind = C->getClauseKind();
12447  AtomicKindLoc = C->getBeginLoc();
12448  if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12449  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12450  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12451  Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12452  << getOpenMPClauseName(AtomicKind);
12453  }
12454  }
12455  break;
12456  }
12457  case OMPC_seq_cst:
12458  case OMPC_acq_rel:
12459  case OMPC_acquire:
12460  case OMPC_release:
12461  case OMPC_relaxed: {
12462  if (MemOrderKind != OMPC_unknown) {
12463  Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12464  << getOpenMPDirectiveName(OMPD_atomic) << 0
12465  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12466  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12467  << getOpenMPClauseName(MemOrderKind);
12468  } else {
12469  MemOrderKind = C->getClauseKind();
12470  MemOrderLoc = C->getBeginLoc();
12471  }
12472  break;
12473  }
12474  // The following clauses are allowed, but we don't need to do anything here.
12475  case OMPC_hint:
12476  break;
12477  default:
12478  llvm_unreachable("unknown clause is encountered");
12479  }
12480  }
12481  bool IsCompareCapture = false;
12482  if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12483  EncounteredAtomicKinds.contains(OMPC_capture)) {
12484  IsCompareCapture = true;
12485  AtomicKind = OMPC_compare;
12486  }
12487  // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12488  // If atomic-clause is read then memory-order-clause must not be acq_rel or
12489  // release.
12490  // If atomic-clause is write then memory-order-clause must not be acq_rel or
12491  // acquire.
12492  // If atomic-clause is update or not present then memory-order-clause must not
12493  // be acq_rel or acquire.
12494  if ((AtomicKind == OMPC_read &&
12495  (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12496  ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12497  AtomicKind == OMPC_unknown) &&
12498  (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12499  SourceLocation Loc = AtomicKindLoc;
12500  if (AtomicKind == OMPC_unknown)
12501  Loc = StartLoc;
12502  Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12503  << getOpenMPClauseName(AtomicKind)
12504  << (AtomicKind == OMPC_unknown ? 1 : 0)
12505  << getOpenMPClauseName(MemOrderKind);
12506  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12507  << getOpenMPClauseName(MemOrderKind);
12508  }
12509 
12510  Stmt *Body = AStmt;
12511  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12512  Body = EWC->getSubExpr();
12513 
12514  Expr *X = nullptr;
12515  Expr *V = nullptr;
12516  Expr *E = nullptr;
12517  Expr *UE = nullptr;
12518  Expr *D = nullptr;
12519  Expr *CE = nullptr;
12520  Expr *R = nullptr;
12521  bool IsXLHSInRHSPart = false;
12522  bool IsPostfixUpdate = false;
12523  bool IsFailOnly = false;
12524  // OpenMP [2.12.6, atomic Construct]
12525  // In the next expressions:
12526  // * x and v (as applicable) are both l-value expressions with scalar type.
12527  // * During the execution of an atomic region, multiple syntactic
12528  // occurrences of x must designate the same storage location.
12529  // * Neither of v and expr (as applicable) may access the storage location
12530  // designated by x.
12531  // * Neither of x and expr (as applicable) may access the storage location
12532  // designated by v.
12533  // * expr is an expression with scalar type.
12534  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12535  // * binop, binop=, ++, and -- are not overloaded operators.
12536  // * The expression x binop expr must be numerically equivalent to x binop
12537  // (expr). This requirement is satisfied if the operators in expr have
12538  // precedence greater than binop, or by using parentheses around expr or
12539  // subexpressions of expr.
12540  // * The expression expr binop x must be numerically equivalent to (expr)
12541  // binop x. This requirement is satisfied if the operators in expr have
12542  // precedence equal to or greater than binop, or by using parentheses around
12543  // expr or subexpressions of expr.
12544  // * For forms that allow multiple occurrences of x, the number of times
12545  // that x is evaluated is unspecified.
12546  if (AtomicKind == OMPC_read) {
12547  enum {
12548  NotAnExpression,
12549  NotAnAssignmentOp,
12550  NotAScalarType,
12551  NotAnLValue,
12552  NoError
12553  } ErrorFound = NoError;
12554  SourceLocation ErrorLoc, NoteLoc;
12555  SourceRange ErrorRange, NoteRange;
12556  // If clause is read:
12557  // v = x;
12558  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12559  const auto *AtomicBinOp =
12560  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12561  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12562  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12563  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12564  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12565  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12566  if (!X->isLValue() || !V->isLValue()) {
12567  const Expr *NotLValueExpr = X->isLValue() ? V : X;
12568  ErrorFound = NotAnLValue;
12569  ErrorLoc = AtomicBinOp->getExprLoc();
12570  ErrorRange = AtomicBinOp->getSourceRange();
12571  NoteLoc = NotLValueExpr->getExprLoc();
12572  NoteRange = NotLValueExpr->getSourceRange();
12573  }
12574  } else if (!X->isInstantiationDependent() ||
12575  !V->isInstantiationDependent()) {
12576  const Expr *NotScalarExpr =
12577  (X->isInstantiationDependent() || X->getType()->isScalarType())
12578  ? V
12579  : X;
12580  ErrorFound = NotAScalarType;
12581  ErrorLoc = AtomicBinOp->getExprLoc();
12582  ErrorRange = AtomicBinOp->getSourceRange();
12583  NoteLoc = NotScalarExpr->getExprLoc();
12584  NoteRange = NotScalarExpr->getSourceRange();
12585  }
12586  } else if (!AtomicBody->isInstantiationDependent()) {
12587  ErrorFound = NotAnAssignmentOp;
12588  ErrorLoc = AtomicBody->getExprLoc();
12589  ErrorRange = AtomicBody->getSourceRange();
12590  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12591  : AtomicBody->getExprLoc();
12592  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12593  : AtomicBody->getSourceRange();
12594  }
12595  } else {
12596  ErrorFound = NotAnExpression;
12597  NoteLoc = ErrorLoc = Body->getBeginLoc();
12598  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12599  }
12600  if (ErrorFound != NoError) {
12601  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12602  << ErrorRange;
12603  Diag(NoteLoc, diag::note_omp_atomic_read_write)
12604  << ErrorFound << NoteRange;
12605  return StmtError();
12606  }
12608  V = X = nullptr;
12609  } else if (AtomicKind == OMPC_write) {
12610  enum {
12611  NotAnExpression,
12612  NotAnAssignmentOp,
12613  NotAScalarType,
12614  NotAnLValue,
12615  NoError
12616  } ErrorFound = NoError;
12617  SourceLocation ErrorLoc, NoteLoc;
12618  SourceRange ErrorRange, NoteRange;
12619  // If clause is write:
12620  // x = expr;
12621  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12622  const auto *AtomicBinOp =
12623  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12624  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12625  X = AtomicBinOp->getLHS();
12626  E = AtomicBinOp->getRHS();
12627  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12628  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12629  if (!X->isLValue()) {
12630  ErrorFound = NotAnLValue;
12631  ErrorLoc = AtomicBinOp->getExprLoc();
12632  ErrorRange = AtomicBinOp->getSourceRange();
12633  NoteLoc = X->getExprLoc();
12634  NoteRange = X->getSourceRange();
12635  }
12636  } else if (!X->isInstantiationDependent() ||
12637  !E->isInstantiationDependent()) {
12638  const Expr *NotScalarExpr =
12639  (X->isInstantiationDependent() || X->getType()->isScalarType())
12640  ? E
12641  : X;
12642  ErrorFound = NotAScalarType;
12643  ErrorLoc = AtomicBinOp->getExprLoc();
12644  ErrorRange = AtomicBinOp->getSourceRange();
12645  NoteLoc = NotScalarExpr->getExprLoc();
12646  NoteRange = NotScalarExpr->getSourceRange();
12647  }
12648  } else if (!AtomicBody->isInstantiationDependent()) {
12649  ErrorFound = NotAnAssignmentOp;
12650  ErrorLoc = AtomicBody->getExprLoc();
12651  ErrorRange = AtomicBody->getSourceRange();
12652  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12653  : AtomicBody->getExprLoc();
12654  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12655  : AtomicBody->getSourceRange();
12656  }
12657  } else {
12658  ErrorFound = NotAnExpression;
12659  NoteLoc = ErrorLoc = Body->getBeginLoc();
12660  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12661  }
12662  if (ErrorFound != NoError) {
12663  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12664  << ErrorRange;
12665  Diag(NoteLoc, diag::note_omp_atomic_read_write)
12666  << ErrorFound << NoteRange;
12667  return StmtError();
12668  }
12670  E = X = nullptr;
12671  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12672  // If clause is update:
12673  // x++;
12674  // x--;
12675  // ++x;
12676  // --x;
12677  // x binop= expr;
12678  // x = x binop expr;
12679  // x = expr binop x;
12680  OpenMPAtomicUpdateChecker Checker(*this);
12681  if (Checker.checkStatement(
12682  Body,
12683  (AtomicKind == OMPC_update)
12684  ? diag::err_omp_atomic_update_not_expression_statement
12685  : diag::err_omp_atomic_not_expression_statement,
12686  diag::note_omp_atomic_update))
12687  return StmtError();
12688  if (!CurContext->isDependentContext()) {
12689  E = Checker.getExpr();
12690  X = Checker.getX();
12691  UE = Checker.getUpdateExpr();
12692  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12693  }
12694  } else if (AtomicKind == OMPC_capture) {
12695  enum {
12696  NotAnAssignmentOp,
12697  NotACompoundStatement,
12698  NotTwoSubstatements,
12699  NotASpecificExpression,
12700  NoError
12701  } ErrorFound = NoError;
12702  SourceLocation ErrorLoc, NoteLoc;
12703  SourceRange ErrorRange, NoteRange;
12704  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12705  // If clause is a capture:
12706  // v = x++;
12707  // v = x--;
12708  // v = ++x;
12709  // v = --x;
12710  // v = x binop= expr;
12711  // v = x = x binop expr;
12712  // v = x = expr binop x;
12713  const auto *AtomicBinOp =
12714  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12715  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12716  V = AtomicBinOp->getLHS();
12717  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12718  OpenMPAtomicUpdateChecker Checker(*this);
12719  if (Checker.checkStatement(
12720  Body, diag::err_omp_atomic_capture_not_expression_statement,
12721  diag::note_omp_atomic_update))
12722  return StmtError();
12723  E = Checker.getExpr();
12724  X = Checker.getX();
12725  UE = Checker.getUpdateExpr();
12726  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12727  IsPostfixUpdate = Checker.isPostfixUpdate();
12728  } else if (!AtomicBody->isInstantiationDependent()) {
12729  ErrorLoc = AtomicBody->getExprLoc();
12730  ErrorRange = AtomicBody->getSourceRange();
12731  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12732  : AtomicBody->getExprLoc();
12733  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12734  : AtomicBody->getSourceRange();
12735  ErrorFound = NotAnAssignmentOp;
12736  }
12737  if (ErrorFound != NoError) {
12738  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12739  << ErrorRange;
12740  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12741  return StmtError();
12742  }
12744  UE = V = E = X = nullptr;
12745  } else {
12746  // If clause is a capture:
12747  // { v = x; x = expr; }
12748  // { v = x; x++; }
12749  // { v = x; x--; }
12750  // { v = x; ++x; }
12751  // { v = x; --x; }
12752  // { v = x; x binop= expr; }
12753  // { v = x; x = x binop expr; }
12754  // { v = x; x = expr binop x; }
12755  // { x++; v = x; }
12756  // { x--; v = x; }
12757  // { ++x; v = x; }
12758  // { --x; v = x; }
12759  // { x binop= expr; v = x; }
12760  // { x = x binop expr; v = x; }
12761  // { x = expr binop x; v = x; }
12762  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12763  // Check that this is { expr1; expr2; }
12764  if (CS->size() == 2) {
12765  Stmt *First = CS->body_front();
12766  Stmt *Second = CS->body_back();
12767  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12768  First = EWC->getSubExpr()->IgnoreParenImpCasts();
12769  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12770  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12771  // Need to find what subexpression is 'v' and what is 'x'.
12772  OpenMPAtomicUpdateChecker Checker(*this);
12773  bool IsUpdateExprFound = !Checker.checkStatement(Second);
12774  BinaryOperator *BinOp = nullptr;
12775  if (IsUpdateExprFound) {
12776  BinOp = dyn_cast<BinaryOperator>(First);
12777  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12778  }
12779  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12780  // { v = x; x++; }
12781  // { v = x; x--; }
12782  // { v = x; ++x; }
12783  // { v = x; --x; }
12784  // { v = x; x binop= expr; }
12785  // { v = x; x = x binop expr; }
12786  // { v = x; x = expr binop x; }
12787  // Check that the first expression has form v = x.
12788  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12789  llvm::FoldingSetNodeID XId, PossibleXId;
12790  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12791  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12792  IsUpdateExprFound = XId == PossibleXId;
12793  if (IsUpdateExprFound) {
12794  V = BinOp->getLHS();
12795  X = Checker.getX();
12796  E = Checker.getExpr();
12797  UE = Checker.getUpdateExpr();
12798  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12799  IsPostfixUpdate = true;
12800  }
12801  }
12802  if (!IsUpdateExprFound) {
12803  IsUpdateExprFound = !Checker.checkStatement(First);
12804  BinOp = nullptr;
12805  if (IsUpdateExprFound) {
12806  BinOp = dyn_cast<BinaryOperator>(Second);
12807  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12808  }
12809  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12810  // { x++; v = x; }
12811  // { x--; v = x; }
12812  // { ++x; v = x; }
12813  // { --x; v = x; }
12814  // { x binop= expr; v = x; }
12815  // { x = x binop expr; v = x; }
12816  // { x = expr binop x; v = x; }
12817  // Check that the second expression has form v = x.
12818  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12819  llvm::FoldingSetNodeID XId, PossibleXId;
12820  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12821  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12822  IsUpdateExprFound = XId == PossibleXId;
12823  if (IsUpdateExprFound) {
12824  V = BinOp->getLHS();
12825  X = Checker.getX();
12826  E = Checker.getExpr();
12827  UE = Checker.getUpdateExpr();
12828  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12829  IsPostfixUpdate = false;
12830  }
12831  }
12832  }
12833  if (!IsUpdateExprFound) {
12834  // { v = x; x = expr; }
12835  auto *FirstExpr = dyn_cast<Expr>(First);
12836  auto *SecondExpr = dyn_cast<Expr>(Second);
12837  if (!FirstExpr || !SecondExpr ||
12838  !(FirstExpr->isInstantiationDependent() ||
12839  SecondExpr->isInstantiationDependent())) {
12840  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12841  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12842  ErrorFound = NotAnAssignmentOp;
12843  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12844  : First->getBeginLoc();
12845  NoteRange = ErrorRange = FirstBinOp
12846  ? FirstBinOp->getSourceRange()
12847  : SourceRange(ErrorLoc, ErrorLoc);
12848  } else {
12849  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12850  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12851  ErrorFound = NotAnAssignmentOp;
12852  NoteLoc = ErrorLoc = SecondBinOp
12853  ? SecondBinOp->getOperatorLoc()
12854  : Second->getBeginLoc();
12855  NoteRange = ErrorRange =
12856  SecondBinOp ? SecondBinOp->getSourceRange()
12857  : SourceRange(ErrorLoc, ErrorLoc);
12858  } else {
12859  Expr *PossibleXRHSInFirst =
12860  FirstBinOp->getRHS()->IgnoreParenImpCasts();
12861  Expr *PossibleXLHSInSecond =
12862  SecondBinOp->getLHS()->IgnoreParenImpCasts();
12863  llvm::FoldingSetNodeID X1Id, X2Id;
12864  PossibleXRHSInFirst->Profile(X1Id, Context,
12865  /*Canonical=*/true);
12866  PossibleXLHSInSecond->Profile(X2Id, Context,
12867  /*Canonical=*/true);
12868  IsUpdateExprFound = X1Id == X2Id;
12869  if (IsUpdateExprFound) {
12870  V = FirstBinOp->getLHS();
12871  X = SecondBinOp->getLHS();
12872  E = SecondBinOp->getRHS();
12873  UE = nullptr;
12874  IsXLHSInRHSPart = false;
12875  IsPostfixUpdate = true;
12876  } else {
12877  ErrorFound = NotASpecificExpression;
12878  ErrorLoc = FirstBinOp->getExprLoc();
12879  ErrorRange = FirstBinOp->getSourceRange();
12880  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12881  NoteRange = SecondBinOp->getRHS()->getSourceRange();
12882  }
12883  }
12884  }
12885  }
12886  }
12887  } else {
12888  NoteLoc = ErrorLoc = Body->getBeginLoc();
12889  NoteRange = ErrorRange =
12890  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12891  ErrorFound = NotTwoSubstatements;
12892  }
12893  } else {
12894  NoteLoc = ErrorLoc = Body->getBeginLoc();
12895  NoteRange = ErrorRange =
12896  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12897  ErrorFound = NotACompoundStatement;
12898  }
12899  }
12900  if (ErrorFound != NoError) {
12901  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12902  << ErrorRange;
12903  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12904  return StmtError();
12905  }
12907  UE = V = E = X = nullptr;
12908  } else if (AtomicKind == OMPC_compare) {
12909  if (IsCompareCapture) {
12910  OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12911  OpenMPAtomicCompareCaptureChecker Checker(*this);
12912  if (!Checker.checkStmt(Body, ErrorInfo)) {
12913  Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12914  << ErrorInfo.ErrorRange;
12915  Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12916  << ErrorInfo.Error << ErrorInfo.NoteRange;
12917  return StmtError();
12918  }
12919  X = Checker.getX();
12920  E = Checker.getE();
12921  D = Checker.getD();
12922  CE = Checker.getCond();
12923  V = Checker.getV();
12924  R = Checker.getR();
12925  // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12926  IsXLHSInRHSPart = Checker.isXBinopExpr();
12927  IsFailOnly = Checker.isFailOnly();
12928  IsPostfixUpdate = Checker.isPostfixUpdate();
12929  } else {
12930  OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12931  OpenMPAtomicCompareChecker Checker(*this);
12932  if (!Checker.checkStmt(Body, ErrorInfo)) {
12933  Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12934  << ErrorInfo.ErrorRange;
12935  Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12936  << ErrorInfo.Error << ErrorInfo.NoteRange;
12937  return StmtError();
12938  }
12939  X = Checker.getX();
12940  E = Checker.getE();
12941  D = Checker.getD();
12942  CE = Checker.getCond();
12943  // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12944  IsXLHSInRHSPart = Checker.isXBinopExpr();
12945  }
12946  }
12947 
12949 
12951  Context, StartLoc, EndLoc, Clauses, AStmt,
12952  {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
12953 }
12954 
12956  Stmt *AStmt,
12957  SourceLocation StartLoc,
12958  SourceLocation EndLoc) {
12959  if (!AStmt)
12960  return StmtError();
12961 
12962  auto *CS = cast<CapturedStmt>(AStmt);
12963  // 1.2.2 OpenMP Language Terminology
12964  // Structured block - An executable statement with a single entry at the
12965  // top and a single exit at the bottom.
12966  // The point of exit cannot be a branch out of the structured block.
12967  // longjmp() and throw() must not violate the entry/exit criteria.
12968  CS->getCapturedDecl()->setNothrow();
12969  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12970  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12971  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12972  // 1.2.2 OpenMP Language Terminology
12973  // Structured block - An executable statement with a single entry at the
12974  // top and a single exit at the bottom.
12975  // The point of exit cannot be a branch out of the structured block.
12976  // longjmp() and throw() must not violate the entry/exit criteria.
12977  CS->getCapturedDecl()->setNothrow();
12978  }
12979 
12980  // OpenMP [2.16, Nesting of Regions]
12981  // If specified, a teams construct must be contained within a target
12982  // construct. That target construct must contain no statements or directives
12983  // outside of the teams construct.
12984  if (DSAStack->hasInnerTeamsRegion()) {
12985  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12986  bool OMPTeamsFound = true;
12987  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12988  auto I = CS->body_begin();
12989  while (I != CS->body_end()) {
12990  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12991  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12992  OMPTeamsFound) {
12993 
12994  OMPTeamsFound = false;
12995  break;
12996  }
12997  ++I;
12998  }
12999  assert(I != CS->body_end() && "Not found statement");
13000  S = *I;
13001  } else {
13002  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13003  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
13004  }
13005  if (!OMPTeamsFound) {
13006  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13007  Diag(DSAStack->getInnerTeamsRegionLoc(),
13008  diag::note_omp_nested_teams_construct_here);
13009  Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13010  << isa<OMPExecutableDirective>(S);
13011  return StmtError();
13012  }
13013  }
13014 
13016 
13017  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13018 }
13019 
13020 StmtResult
13022  Stmt *AStmt, SourceLocation StartLoc,
13023  SourceLocation EndLoc) {
13024  if (!AStmt)
13025  return StmtError();
13026 
13027  auto *CS = cast<CapturedStmt>(AStmt);
13028  // 1.2.2 OpenMP Language Terminology
13029  // Structured block - An executable statement with a single entry at the
13030  // top and a single exit at the bottom.
13031  // The point of exit cannot be a branch out of the structured block.
13032  // longjmp() and throw() must not violate the entry/exit criteria.
13033  CS->getCapturedDecl()->setNothrow();
13034  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13035  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13036  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13037  // 1.2.2 OpenMP Language Terminology
13038  // Structured block - An executable statement with a single entry at the
13039  // top and a single exit at the bottom.
13040  // The point of exit cannot be a branch out of the structured block.
13041  // longjmp() and throw() must not violate the entry/exit criteria.
13042  CS->getCapturedDecl()->setNothrow();
13043  }
13044 
13046 
13048  Context, StartLoc, EndLoc, Clauses, AStmt,
13049  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13050 }
13051 
13053  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13054  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13055  if (!AStmt)
13056  return StmtError();
13057 
13058  auto *CS = cast<CapturedStmt>(AStmt);
13059  // 1.2.2 OpenMP Language Terminology
13060  // Structured block - An executable statement with a single entry at the
13061  // top and a single exit at the bottom.
13062  // The point of exit cannot be a branch out of the structured block.
13063  // longjmp() and throw() must not violate the entry/exit criteria.
13064  CS->getCapturedDecl()->setNothrow();
13065  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13066  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13067  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13068  // 1.2.2 OpenMP Language Terminology
13069  // Structured block - An executable statement with a single entry at the
13070  // top and a single exit at the bottom.
13071  // The point of exit cannot be a branch out of the structured block.
13072  // longjmp() and throw() must not violate the entry/exit criteria.
13073  CS->getCapturedDecl()->setNothrow();
13074  }
13075 
13077  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13078  // define the nested loops number.
13079  unsigned NestedLoopCount =
13080  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13081  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13082  VarsWithImplicitDSA, B);
13083  if (NestedLoopCount == 0)
13084  return StmtError();
13085 
13086  assert((CurContext->isDependentContext() || B.builtAll()) &&
13087  "omp target parallel for loop exprs were not built");
13088 
13089  if (!CurContext->isDependentContext()) {
13090  // Finalize the clauses that need pre-built expressions for CodeGen.
13091  for (OMPClause *C : Clauses) {
13092  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13093  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13094  B.NumIterations, *this, CurScope,
13095  DSAStack))
13096  return StmtError();
13097  }
13098  }
13099 
13102  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13103  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13104 }
13105 
13106 /// Check for existence of a map clause in the list of clauses.
13107 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13108  const OpenMPClauseKind K) {
13109  return llvm::any_of(
13110  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13111 }
13112 
13113 template <typename... Params>
13115  const Params... ClauseTypes) {
13116  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13117 }
13118 
13119 /// Check if the variables in the mapping clause are externally visible.
13121  for (const OMPClause *C : Clauses) {
13122  if (auto *TC = dyn_cast<OMPToClause>(C))
13123  return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13124  return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13125  (VD->isExternallyVisible() &&
13126  VD->getVisibility() != HiddenVisibility);
13127  });
13128  else if (auto *FC = dyn_cast<OMPFromClause>(C))
13129  return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13130  return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13131  (VD->isExternallyVisible() &&
13132  VD->getVisibility() != HiddenVisibility);
13133  });
13134  }
13135 
13136  return true;
13137 }
13138 
13140  Stmt *AStmt,
13141  SourceLocation StartLoc,
13142  SourceLocation EndLoc) {
13143  if (!AStmt)
13144  return StmtError();
13145 
13146  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13147 
13148  // OpenMP [2.12.2, target data Construct, Restrictions]
13149  // At least one map, use_device_addr or use_device_ptr clause must appear on
13150  // the directive.
13151  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13152  (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13153  StringRef Expected;
13154  if (LangOpts.OpenMP < 50)
13155  Expected = "'map' or 'use_device_ptr'";
13156  else
13157  Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13158  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13159  << Expected << getOpenMPDirectiveName(OMPD_target_data);
13160  return StmtError();
13161  }
13162 
13164 
13165  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13166  AStmt);
13167 }
13168 
13169 StmtResult
13171  SourceLocation StartLoc,
13172  SourceLocation EndLoc, Stmt *AStmt) {
13173  if (!AStmt)
13174  return StmtError();
13175 
13176  auto *CS = cast<CapturedStmt>(AStmt);
13177  // 1.2.2 OpenMP Language Terminology
13178  // Structured block - An executable statement with a single entry at the
13179  // top and a single exit at the bottom.
13180  // The point of exit cannot be a branch out of the structured block.
13181  // longjmp() and throw() must not violate the entry/exit criteria.
13182  CS->getCapturedDecl()->setNothrow();
13183  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13184  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13185  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13186  // 1.2.2 OpenMP Language Terminology
13187  // Structured block - An executable statement with a single entry at the
13188  // top and a single exit at the bottom.
13189  // The point of exit cannot be a branch out of the structured block.
13190  // longjmp() and throw() must not violate the entry/exit criteria.
13191  CS->getCapturedDecl()->setNothrow();
13192  }
13193 
13194  // OpenMP [2.10.2, Restrictions, p. 99]
13195  // At least one map clause must appear on the directive.
13196  if (!hasClauses(Clauses, OMPC_map)) {
13197  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13198  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13199  return StmtError();
13200  }
13201 
13202  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13203  AStmt);
13204 }
13205 
13206 StmtResult
13208  SourceLocation StartLoc,
13209  SourceLocation EndLoc, Stmt *AStmt) {
13210  if (!AStmt)
13211  return StmtError();
13212 
13213  auto *CS = cast<CapturedStmt>(AStmt);
13214  // 1.2.2 OpenMP Language Terminology
13215  // Structured block - An executable statement with a single entry at the
13216  // top and a single exit at the bottom.
13217  // The point of exit cannot be a branch out of the structured block.
13218  // longjmp() and throw() must not violate the entry/exit criteria.
13219  CS->getCapturedDecl()->setNothrow();
13220  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13221  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13222  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13223  // 1.2.2 OpenMP Language Terminology
13224  // Structured block - An executable statement with a single entry at the
13225  // top and a single exit at the bottom.
13226  // The point of exit cannot be a branch out of the structured block.
13227  // longjmp() and throw() must not violate the entry/exit criteria.
13228  CS->getCapturedDecl()->setNothrow();
13229  }
13230 
13231  // OpenMP [2.10.3, Restrictions, p. 102]
13232  // At least one map clause must appear on the directive.
13233  if (!hasClauses(Clauses, OMPC_map)) {
13234  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13235  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13236  return StmtError();
13237  }
13238 
13239  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13240  AStmt);
13241 }
13242 
13244  SourceLocation StartLoc,
13245  SourceLocation EndLoc,
13246  Stmt *AStmt) {
13247  if (!AStmt)
13248  return StmtError();
13249 
13250  auto *CS = cast<CapturedStmt>(AStmt);
13251  // 1.2.2 OpenMP Language Terminology
13252  // Structured block - An executable statement with a single entry at the
13253  // top and a single exit at the bottom.
13254  // The point of exit cannot be a branch out of the structured block.
13255  // longjmp() and throw() must not violate the entry/exit criteria.
13256  CS->getCapturedDecl()->setNothrow();
13257  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13258  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13259  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13260  // 1.2.2 OpenMP Language Terminology
13261  // Structured block - An executable statement with a single entry at the
13262  // top and a single exit at the bottom.
13263  // The point of exit cannot be a branch out of the structured block.
13264  // longjmp() and throw() must not violate the entry/exit criteria.
13265  CS->getCapturedDecl()->setNothrow();
13266  }
13267 
13268  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13269  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13270  return StmtError();
13271  }
13272 
13273  if (!isClauseMappable(Clauses)) {
13274  Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13275  return StmtError();
13276  }
13277 
13278  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13279  AStmt);
13280 }
13281 
13283  Stmt *AStmt, SourceLocation StartLoc,
13284  SourceLocation EndLoc) {
13285  if (!AStmt)
13286  return StmtError();
13287 
13288  auto *CS = cast<CapturedStmt>(AStmt);
13289  // 1.2.2 OpenMP Language Terminology
13290  // Structured block - An executable statement with a single entry at the
13291  // top and a single exit at the bottom.
13292  // The point of exit cannot be a branch out of the structured block.
13293  // longjmp() and throw() must not violate the entry/exit criteria.
13294  CS->getCapturedDecl()->setNothrow();
13295 
13297 
13298  DSAStack->setParentTeamsRegionLoc(StartLoc);
13299 
13300  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13301 }
13302 
13303 StmtResult
13305  SourceLocation EndLoc,
13306  OpenMPDirectiveKind CancelRegion) {
13307  if (DSAStack->isParentNowaitRegion()) {
13308  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13309  return StmtError();
13310  }
13311  if (DSAStack->isParentOrderedRegion()) {
13312  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13313  return StmtError();
13314  }
13315  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13316  CancelRegion);
13317 }
13318 
13320  SourceLocation StartLoc,
13321  SourceLocation EndLoc,
13322  OpenMPDirectiveKind CancelRegion) {
13323  if (DSAStack->isParentNowaitRegion()) {
13324  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13325  return StmtError();
13326  }
13327  if (DSAStack->isParentOrderedRegion()) {
13328  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13329  return StmtError();
13330  }
13331  DSAStack->setParentCancelRegion(/*Cancel=*/true);
13332  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13333  CancelRegion);
13334 }
13335 
13337  ArrayRef<OMPClause *> Clauses) {
13338  const OMPClause *ReductionClause = nullptr;
13339  const OMPClause *NogroupClause = nullptr;
13340  for (const OMPClause *C : Clauses) {
13341  if (C->getClauseKind() == OMPC_reduction) {
13342  ReductionClause = C;
13343  if (NogroupClause)
13344  break;
13345  continue;
13346  }
13347  if (C->getClauseKind() == OMPC_nogroup) {
13348  NogroupClause = C;
13349  if (ReductionClause)
13350  break;
13351  continue;
13352  }
13353  }
13354  if (ReductionClause && NogroupClause) {
13355  S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13356  << SourceRange(NogroupClause->getBeginLoc(),
13357  NogroupClause->getEndLoc());
13358  return true;
13359  }
13360  return false;
13361 }
13362 
13364  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13365  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13366  if (!AStmt)
13367  return StmtError();
13368 
13369  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13371  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13372  // define the nested loops number.
13373  unsigned NestedLoopCount =
13374  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13375  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13376  VarsWithImplicitDSA, B);
13377  if (NestedLoopCount == 0)
13378  return StmtError();
13379 
13380  assert((CurContext->isDependentContext() || B.builtAll()) &&
13381  "omp for loop exprs were not built");
13382 
13383  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13384  // The grainsize clause and num_tasks clause are mutually exclusive and may
13385  // not appear on the same taskloop directive.
13386  if (checkMutuallyExclusiveClauses(*this, Clauses,
13387  {OMPC_grainsize, OMPC_num_tasks}))
13388  return StmtError();
13389  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13390  // If a reduction clause is present on the taskloop directive, the nogroup
13391  // clause must not be specified.
13392  if (checkReductionClauseWithNogroup(*this, Clauses))
13393  return StmtError();
13394 
13396  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13397  NestedLoopCount, Clauses, AStmt, B,
13398  DSAStack->isCancelRegion());
13399 }
13400 
13402  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13403  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13404  if (!AStmt)
13405  return StmtError();
13406 
13407  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13409  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13410  // define the nested loops number.
13411  unsigned NestedLoopCount =
13412  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13413  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13414  VarsWithImplicitDSA, B);
13415  if (NestedLoopCount == 0)
13416  return StmtError();
13417 
13418  assert((CurContext->isDependentContext() || B.builtAll()) &&
13419  "omp for loop exprs were not built");
13420 
13421  if (!CurContext->isDependentContext()) {
13422  // Finalize the clauses that need pre-built expressions for CodeGen.
13423  for (OMPClause *C : Clauses) {
13424  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13425  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13426  B.NumIterations, *this, CurScope,
13427  DSAStack))
13428  return StmtError();
13429  }
13430  }
13431 
13432  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13433  // The grainsize clause and num_tasks clause are mutually exclusive and may
13434  // not appear on the same taskloop directive.
13435  if (checkMutuallyExclusiveClauses(*this, Clauses,
13436  {OMPC_grainsize, OMPC_num_tasks}))
13437  return StmtError();
13438  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13439  // If a reduction clause is present on the taskloop directive, the nogroup
13440  // clause must not be specified.
13441  if (checkReductionClauseWithNogroup(*this, Clauses))
13442  return StmtError();
13443  if (checkSimdlenSafelenSpecified(*this, Clauses))
13444  return StmtError();
13445 
13447  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13448  NestedLoopCount, Clauses, AStmt, B);
13449 }
13450 
13452  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13453  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13454  if (!AStmt)
13455  return StmtError();
13456 
13457  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13459  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13460  // define the nested loops number.
13461  unsigned NestedLoopCount =
13462  checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13463  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13464  VarsWithImplicitDSA, B);
13465  if (NestedLoopCount == 0)
13466  return StmtError();
13467 
13468  assert((CurContext->isDependentContext() || B.builtAll()) &&
13469  "omp for loop exprs were not built");
13470 
13471  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13472  // The grainsize clause and num_tasks clause are mutually exclusive and may
13473  // not appear on the same taskloop directive.
13474  if (checkMutuallyExclusiveClauses(*this, Clauses,
13475  {OMPC_grainsize, OMPC_num_tasks}))
13476  return StmtError();
13477  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13478  // If a reduction clause is present on the taskloop directive, the nogroup
13479  // clause must not be specified.
13480  if (checkReductionClauseWithNogroup(*this, Clauses))
13481  return StmtError();
13482 
13484  return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13485  NestedLoopCount, Clauses, AStmt, B,
13486  DSAStack->isCancelRegion());
13487 }
13488 
13490  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13491  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13492  if (!AStmt)
13493  return StmtError();
13494 
13495  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13497  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13498  // define the nested loops number.
13499  unsigned NestedLoopCount =
13500  checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13501  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13502  VarsWithImplicitDSA, B);
13503  if (NestedLoopCount == 0)
13504  return StmtError();
13505 
13506  assert((CurContext->isDependentContext() || B.builtAll()) &&
13507  "omp for loop exprs were not built");
13508 
13509  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13510  // The grainsize clause and num_tasks clause are mutually exclusive and may
13511  // not appear on the same taskloop directive.
13512  if (checkMutuallyExclusiveClauses(*this, Clauses,
13513  {OMPC_grainsize, OMPC_num_tasks}))
13514  return StmtError();
13515  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13516  // If a reduction clause is present on the taskloop directive, the nogroup
13517  // clause must not be specified.
13518  if (checkReductionClauseWithNogroup(*this, Clauses))
13519  return StmtError();
13520 
13522  return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13523  NestedLoopCount, Clauses, AStmt, B,
13524  DSAStack->isCancelRegion());
13525 }
13526 
13528  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13529  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13530  if (!AStmt)
13531  return StmtError();
13532 
13533  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13535  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13536  // define the nested loops number.
13537  unsigned NestedLoopCount =
13538  checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13539  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13540  VarsWithImplicitDSA, B);
13541  if (NestedLoopCount == 0)
13542  return StmtError();
13543 
13544  assert((CurContext->isDependentContext() || B.builtAll()) &&
13545  "omp for loop exprs were not built");
13546 
13547  if (!CurContext->isDependentContext()) {
13548  // Finalize the clauses that need pre-built expressions for CodeGen.
13549  for (OMPClause *C : Clauses) {
13550  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13551  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13552  B.NumIterations, *this, CurScope,
13553  DSAStack))
13554  return StmtError();
13555  }
13556  }
13557 
13558  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13559  // The grainsize clause and num_tasks clause are mutually exclusive and may
13560  // not appear on the same taskloop directive.
13561  if (checkMutuallyExclusiveClauses(*this, Clauses,
13562  {OMPC_grainsize, OMPC_num_tasks}))
13563  return StmtError();
13564  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13565  // If a reduction clause is present on the taskloop directive, the nogroup
13566  // clause must not be specified.
13567  if (checkReductionClauseWithNogroup(*this, Clauses))
13568  return StmtError();
13569  if (checkSimdlenSafelenSpecified(*this, Clauses))
13570  return StmtError();
13571 
13574  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13575 }
13576 
13578  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13579  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13580  if (!AStmt)
13581  return StmtError();
13582 
13583  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13585  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13586  // define the nested loops number.
13587  unsigned NestedLoopCount =
13588  checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13589  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13590  VarsWithImplicitDSA, B);
13591  if (NestedLoopCount == 0)
13592  return StmtError();
13593 
13594  assert((CurContext->isDependentContext() || B.builtAll()) &&
13595  "omp for loop exprs were not built");
13596 
13597  if (!CurContext->isDependentContext()) {
13598  // Finalize the clauses that need pre-built expressions for CodeGen.
13599  for (OMPClause *C : Clauses) {
13600  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13601  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13602  B.NumIterations, *this, CurScope,
13603  DSAStack))
13604  return StmtError();
13605  }
13606  }
13607 
13608  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13609  // The grainsize clause and num_tasks clause are mutually exclusive and may
13610  // not appear on the same taskloop directive.
13611  if (checkMutuallyExclusiveClauses(*this, Clauses,
13612  {OMPC_grainsize, OMPC_num_tasks}))
13613  return StmtError();
13614  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13615  // If a reduction clause is present on the taskloop directive, the nogroup
13616  // clause must not be specified.
13617  if (checkReductionClauseWithNogroup(*this, Clauses))
13618  return StmtError();
13619  if (checkSimdlenSafelenSpecified(*this, Clauses))
13620  return StmtError();
13621 
13624  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13625 }
13626 
13628  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13629  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13630  if (!AStmt)
13631  return StmtError();
13632 
13633  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13634  auto *CS = cast<CapturedStmt>(AStmt);
13635  // 1.2.2 OpenMP Language Terminology
13636  // Structured block - An executable statement with a single entry at the
13637  // top and a single exit at the bottom.
13638  // The point of exit cannot be a branch out of the structured block.
13639  // longjmp() and throw() must not violate the entry/exit criteria.
13640  CS->getCapturedDecl()->setNothrow();
13641  for (int ThisCaptureLevel =
13642  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13643  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13644  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13645  // 1.2.2 OpenMP Language Terminology
13646  // Structured block - An executable statement with a single entry at the
13647  // top and a single exit at the bottom.
13648  // The point of exit cannot be a branch out of the structured block.
13649  // longjmp() and throw() must not violate the entry/exit criteria.
13650  CS->getCapturedDecl()->setNothrow();
13651  }
13652 
13654  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13655  // define the nested loops number.
13656  unsigned NestedLoopCount = checkOpenMPLoop(
13657  OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13658  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13659  VarsWithImplicitDSA, B);
13660  if (NestedLoopCount == 0)
13661  return StmtError();
13662 
13663  assert((CurContext->isDependentContext() || B.builtAll()) &&
13664  "omp for loop exprs were not built");
13665 
13666  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13667  // The grainsize clause and num_tasks clause are mutually exclusive and may
13668  // not appear on the same taskloop directive.
13669  if (checkMutuallyExclusiveClauses(*this, Clauses,
13670  {OMPC_grainsize, OMPC_num_tasks}))
13671  return StmtError();
13672  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13673  // If a reduction clause is present on the taskloop directive, the nogroup
13674  // clause must not be specified.
13675  if (checkReductionClauseWithNogroup(*this, Clauses))
13676  return StmtError();
13677 
13680  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13681  DSAStack->isCancelRegion());
13682 }
13683 
13685  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13686  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13687  if (!AStmt)
13688  return StmtError();
13689 
13690  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13691  auto *CS = cast<CapturedStmt>(AStmt);
13692  // 1.2.2 OpenMP Language Terminology
13693  // Structured block - An executable statement with a single entry at the
13694  // top and a single exit at the bottom.
13695  // The point of exit cannot be a branch out of the structured block.
13696  // longjmp() and throw() must not violate the entry/exit criteria.
13697  CS->getCapturedDecl()->setNothrow();
13698  for (int ThisCaptureLevel =
13699  getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13700  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13701  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13702  // 1.2.2 OpenMP Language Terminology
13703  // Structured block - An executable statement with a single entry at the
13704  // top and a single exit at the bottom.
13705  // The point of exit cannot be a branch out of the structured block.
13706  // longjmp() and throw() must not violate the entry/exit criteria.
13707  CS->getCapturedDecl()->setNothrow();
13708  }
13709 
13711  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13712  // define the nested loops number.
13713  unsigned NestedLoopCount = checkOpenMPLoop(
13714  OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13715  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13716  VarsWithImplicitDSA, B);
13717  if (NestedLoopCount == 0)
13718  return StmtError();
13719 
13720  assert((CurContext->isDependentContext() || B.builtAll()) &&
13721  "omp for loop exprs were not built");
13722 
13723  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13724  // The grainsize clause and num_tasks clause are mutually exclusive and may
13725  // not appear on the same taskloop directive.
13726  if (checkMutuallyExclusiveClauses(*this, Clauses,
13727  {OMPC_grainsize, OMPC_num_tasks}))
13728  return StmtError();
13729  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13730  // If a reduction clause is present on the taskloop directive, the nogroup
13731  // clause must not be specified.
13732  if (checkReductionClauseWithNogroup(*this, Clauses))
13733  return StmtError();
13734 
13737  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13738  DSAStack->isCancelRegion());
13739 }
13740 
13742  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13743  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13744  if (!AStmt)
13745  return StmtError();
13746 
13747  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13748  auto *CS = cast<CapturedStmt>(AStmt);
13749  // 1.2.2 OpenMP Language Terminology
13750  // Structured block - An executable statement with a single entry at the
13751  // top and a single exit at the bottom.
13752  // The point of exit cannot be a branch out of the structured block.
13753  // longjmp() and throw() must not violate the entry/exit criteria.
13754  CS->getCapturedDecl()->setNothrow();
13755  for (int ThisCaptureLevel =
13756  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13757  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13758  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13759  // 1.2.2 OpenMP Language Terminology
13760  // Structured block - An executable statement with a single entry at the
13761  // top and a single exit at the bottom.
13762  // The point of exit cannot be a branch out of the structured block.
13763  // longjmp() and throw() must not violate the entry/exit criteria.
13764  CS->getCapturedDecl()->setNothrow();
13765  }
13766 
13768  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13769  // define the nested loops number.
13770  unsigned NestedLoopCount = checkOpenMPLoop(
13771  OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13772  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13773  VarsWithImplicitDSA, B);
13774  if (NestedLoopCount == 0)
13775  return StmtError();
13776 
13777  assert((CurContext->isDependentContext() || B.builtAll()) &&
13778  "omp for loop exprs were not built");
13779 
13780  if (!CurContext->isDependentContext()) {
13781  // Finalize the clauses that need pre-built expressions for CodeGen.
13782  for (OMPClause *C : Clauses) {
13783  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13784  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13785  B.NumIterations, *this, CurScope,
13786  DSAStack))
13787  return StmtError();
13788  }
13789  }
13790 
13791  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13792  // The grainsize clause and num_tasks clause are mutually exclusive and may
13793  // not appear on the same taskloop directive.
13794  if (checkMutuallyExclusiveClauses(*this, Clauses,
13795  {OMPC_grainsize, OMPC_num_tasks}))
13796  return StmtError();
13797  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13798  // If a reduction clause is present on the taskloop directive, the nogroup
13799  // clause must not be specified.
13800  if (checkReductionClauseWithNogroup(*this, Clauses))
13801  return StmtError();
13802  if (checkSimdlenSafelenSpecified(*this, Clauses))
13803  return StmtError();
13804 
13807  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13808 }
13809 
13811  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13812  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13813  if (!AStmt)
13814  return StmtError();
13815 
13816  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13817  auto *CS = cast<CapturedStmt>(AStmt);
13818  // 1.2.2 OpenMP Language Terminology
13819  // Structured block - An executable statement with a single entry at the
13820  // top and a single exit at the bottom.
13821  // The point of exit cannot be a branch out of the structured block.
13822  // longjmp() and throw() must not violate the entry/exit criteria.
13823  CS->getCapturedDecl()->setNothrow();
13824  for (int ThisCaptureLevel =
13825  getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
13826  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13827  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13828  // 1.2.2 OpenMP Language Terminology
13829  // Structured block - An executable statement with a single entry at the
13830  // top and a single exit at the bottom.
13831  // The point of exit cannot be a branch out of the structured block.
13832  // longjmp() and throw() must not violate the entry/exit criteria.
13833  CS->getCapturedDecl()->setNothrow();
13834  }
13835 
13837  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13838  // define the nested loops number.
13839  unsigned NestedLoopCount = checkOpenMPLoop(
13840  OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13841  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13842  VarsWithImplicitDSA, B);
13843  if (NestedLoopCount == 0)
13844  return StmtError();
13845 
13846  assert((CurContext->isDependentContext() || B.builtAll()) &&
13847  "omp for loop exprs were not built");
13848 
13849  if (!CurContext->isDependentContext()) {
13850  // Finalize the clauses that need pre-built expressions for CodeGen.
13851  for (OMPClause *C : Clauses) {
13852  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13853  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13854  B.NumIterations, *this, CurScope,
13855  DSAStack))
13856  return StmtError();
13857  }
13858  }
13859 
13860  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13861  // The grainsize clause and num_tasks clause are mutually exclusive and may
13862  // not appear on the same taskloop directive.
13863  if (checkMutuallyExclusiveClauses(*this, Clauses,
13864  {OMPC_grainsize, OMPC_num_tasks}))
13865  return StmtError();
13866  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13867  // If a reduction clause is present on the taskloop directive, the nogroup
13868  // clause must not be specified.
13869  if (checkReductionClauseWithNogroup(*this, Clauses))
13870  return StmtError();
13871  if (checkSimdlenSafelenSpecified(*this, Clauses))
13872  return StmtError();
13873 
13876  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13877 }
13878 
13880  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13881  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13882  if (!AStmt)
13883  return StmtError();
13884 
13885  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13887  // In presence of clause 'collapse' with number of loops, it will
13888  // define the nested loops number.
13889  unsigned NestedLoopCount =
13890  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13891  nullptr /*ordered not a clause on distribute*/, AStmt,
13892  *this, *DSAStack, VarsWithImplicitDSA, B);
13893  if (NestedLoopCount == 0)
13894  return StmtError();
13895 
13896  assert((CurContext->isDependentContext() || B.builtAll()) &&
13897  "omp for loop exprs were not built");
13898 
13900  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13901  NestedLoopCount, Clauses, AStmt, B);
13902 }
13903 
13905  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13906  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13907  if (!AStmt)
13908  return StmtError();
13909 
13910  auto *CS = cast<CapturedStmt>(AStmt);
13911  // 1.2.2 OpenMP Language Terminology
13912  // Structured block - An executable statement with a single entry at the
13913  // top and a single exit at the bottom.
13914  // The point of exit cannot be a branch out of the structured block.
13915  // longjmp() and throw() must not violate the entry/exit criteria.
13916  CS->getCapturedDecl()->setNothrow();
13917  for (int ThisCaptureLevel =
13918  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13919  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13920  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13921  // 1.2.2 OpenMP Language Terminology
13922  // Structured block - An executable statement with a single entry at the
13923  // top and a single exit at the bottom.
13924  // The point of exit cannot be a branch out of the structured block.
13925  // longjmp() and throw() must not violate the entry/exit criteria.
13926  CS->getCapturedDecl()->setNothrow();
13927  }
13928 
13930  // In presence of clause 'collapse' with number of loops, it will
13931  // define the nested loops number.
13932  unsigned NestedLoopCount = checkOpenMPLoop(
13933  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13934  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13935  VarsWithImplicitDSA, B);
13936  if (NestedLoopCount == 0)
13937  return StmtError();
13938 
13939  assert((CurContext->isDependentContext() || B.builtAll()) &&
13940  "omp for loop exprs were not built");
13941 
13944  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13945  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13946 }
13947 
13949  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13950  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13951  if (!AStmt)
13952  return StmtError();
13953 
13954  auto *CS = cast<CapturedStmt>(AStmt);
13955  // 1.2.2 OpenMP Language Terminology
13956  // Structured block - An executable statement with a single entry at the
13957  // top and a single exit at the bottom.
13958  // The point of exit cannot be a branch out of the structured block.
13959  // longjmp() and throw() must not violate the entry/exit criteria.
13960  CS->getCapturedDecl()->setNothrow();
13961  for (int ThisCaptureLevel =
13962  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13963  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13964  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13965  // 1.2.2 OpenMP Language Terminology
13966  // Structured block - An executable statement with a single entry at the
13967  // top and a single exit at the bottom.
13968  // The point of exit cannot be a branch out of the structured block.
13969  // longjmp() and throw() must not violate the entry/exit criteria.
13970  CS->getCapturedDecl()->setNothrow();
13971  }
13972 
13974  // In presence of clause 'collapse' with number of loops, it will
13975  // define the nested loops number.
13976  unsigned NestedLoopCount = checkOpenMPLoop(
13977  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13978  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13979  VarsWithImplicitDSA, B);
13980  if (NestedLoopCount == 0)
13981  return StmtError();
13982 
13983  assert((CurContext->isDependentContext() || B.builtAll()) &&
13984  "omp for loop exprs were not built");
13985 
13986  if (!CurContext->isDependentContext()) {
13987  // Finalize the clauses that need pre-built expressions for CodeGen.
13988  for (OMPClause *C : Clauses) {
13989  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13990  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13991  B.NumIterations, *this, CurScope,
13992  DSAStack))
13993  return StmtError();
13994  }
13995  }
13996 
13997  if (checkSimdlenSafelenSpecified(*this, Clauses))
13998  return StmtError();
13999 
14002  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14003 }
14004 
14006  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14007  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14008  if (!AStmt)
14009  return StmtError();
14010 
14011  auto *CS = cast<CapturedStmt>(AStmt);
14012  // 1.2.2 OpenMP Language Terminology
14013  // Structured block - An executable statement with a single entry at the
14014  // top and a single exit at the bottom.
14015  // The point of exit cannot be a branch out of the structured block.
14016  // longjmp() and throw() must not violate the entry/exit criteria.
14017  CS->getCapturedDecl()->setNothrow();
14018  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14019  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14020  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14021  // 1.2.2 OpenMP Language Terminology
14022  // Structured block - An executable statement with a single entry at the
14023  // top and a single exit at the bottom.
14024  // The point of exit cannot be a branch out of the structured block.
14025  // longjmp() and throw() must not violate the entry/exit criteria.
14026  CS->getCapturedDecl()->setNothrow();
14027  }
14028 
14030  // In presence of clause 'collapse' with number of loops, it will
14031  // define the nested loops number.
14032  unsigned NestedLoopCount =
14033  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14034  nullptr /*ordered not a clause on distribute*/, CS, *this,
14035  *DSAStack, VarsWithImplicitDSA, B);
14036  if (NestedLoopCount == 0)
14037  return StmtError();
14038 
14039  assert((CurContext->isDependentContext() || B.builtAll()) &&
14040  "omp for loop exprs were not built");
14041 
14042  if (!CurContext->isDependentContext()) {
14043  // Finalize the clauses that need pre-built expressions for CodeGen.
14044  for (OMPClause *C : Clauses) {
14045  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14046  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14047  B.NumIterations, *this, CurScope,
14048  DSAStack))
14049  return StmtError();
14050  }
14051  }
14052 
14053  if (checkSimdlenSafelenSpecified(*this, Clauses))
14054  return StmtError();
14055 
14057  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14058  NestedLoopCount, Clauses, AStmt, B);
14059 }
14060 
14062  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14063  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14064  if (!AStmt)
14065  return StmtError();
14066 
14067  auto *CS = cast<CapturedStmt>(AStmt);
14068  // 1.2.2 OpenMP Language Terminology
14069  // Structured block - An executable statement with a single entry at the
14070  // top and a single exit at the bottom.
14071  // The point of exit cannot be a branch out of the structured block.
14072  // longjmp() and throw() must not violate the entry/exit criteria.
14073  CS->getCapturedDecl()->setNothrow();
14074  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14075  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14076  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14077  // 1.2.2 OpenMP Language Terminology
14078  // Structured block - An executable statement with a single entry at the
14079  // top and a single exit at the bottom.
14080  // The point of exit cannot be a branch out of the structured block.
14081  // longjmp() and throw() must not violate the entry/exit criteria.
14082  CS->getCapturedDecl()->setNothrow();
14083  }
14084 
14086  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14087  // define the nested loops number.
14088  unsigned NestedLoopCount = checkOpenMPLoop(
14089  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14090  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14091  B);
14092  if (NestedLoopCount == 0)
14093  return StmtError();
14094 
14095  assert((CurContext->isDependentContext() || B.builtAll()) &&
14096  "omp target parallel for simd loop exprs were not built");
14097 
14098  if (!CurContext->isDependentContext()) {
14099  // Finalize the clauses that need pre-built expressions for CodeGen.
14100  for (OMPClause *C : Clauses) {
14101  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14102  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14103  B.NumIterations, *this, CurScope,
14104  DSAStack))
14105  return StmtError();
14106  }
14107  }
14108  if (checkSimdlenSafelenSpecified(*this, Clauses))
14109  return StmtError();
14110 
14113  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14114 }
14115 
14117  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14118  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14119  if (!AStmt)
14120  return StmtError();
14121 
14122  auto *CS = cast<CapturedStmt>(AStmt);
14123  // 1.2.2 OpenMP Language Terminology
14124  // Structured block - An executable statement with a single entry at the
14125  // top and a single exit at the bottom.
14126  // The point of exit cannot be a branch out of the structured block.
14127  // longjmp() and throw() must not violate the entry/exit criteria.
14128  CS->getCapturedDecl()->setNothrow();
14129  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14130  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14131  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14132  // 1.2.2 OpenMP Language Terminology
14133  // Structured block - An executable statement with a single entry at the
14134  // top and a single exit at the bottom.
14135  // The point of exit cannot be a branch out of the structured block.
14136  // longjmp() and throw() must not violate the entry/exit criteria.
14137  CS->getCapturedDecl()->setNothrow();
14138  }
14139 
14141  // In presence of clause 'collapse' with number of loops, it will define the
14142  // nested loops number.
14143  unsigned NestedLoopCount =
14144  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14145  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14146  VarsWithImplicitDSA, B);
14147  if (NestedLoopCount == 0)
14148  return StmtError();
14149 
14150  assert((CurContext->isDependentContext() || B.builtAll()) &&
14151  "omp target simd loop exprs were not built");
14152 
14153  if (!CurContext->isDependentContext()) {
14154  // Finalize the clauses that need pre-built expressions for CodeGen.
14155  for (OMPClause *C : Clauses) {
14156  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14157  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14158  B.NumIterations, *this, CurScope,
14159  DSAStack))
14160  return StmtError();
14161  }
14162  }
14163 
14164  if (checkSimdlenSafelenSpecified(*this, Clauses))
14165  return StmtError();
14166 
14168  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14169  NestedLoopCount, Clauses, AStmt, B);
14170 }
14171 
14173  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14174  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14175  if (!AStmt)
14176  return StmtError();
14177 
14178  auto *CS = cast<CapturedStmt>(AStmt);
14179  // 1.2.2 OpenMP Language Terminology
14180  // Structured block - An executable statement with a single entry at the
14181  // top and a single exit at the bottom.
14182  // The point of exit cannot be a branch out of the structured block.
14183  // longjmp() and throw() must not violate the entry/exit criteria.
14184  CS->getCapturedDecl()->setNothrow();
14185  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14186  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14187  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14188  // 1.2.2 OpenMP Language Terminology
14189  // Structured block - An executable statement with a single entry at the
14190  // top and a single exit at the bottom.
14191  // The point of exit cannot be a branch out of the structured block.
14192  // longjmp() and throw() must not violate the entry/exit criteria.
14193  CS->getCapturedDecl()->setNothrow();
14194  }
14195 
14197  // In presence of clause 'collapse' with number of loops, it will
14198  // define the nested loops number.
14199  unsigned NestedLoopCount =
14200  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14201  nullptr /*ordered not a clause on distribute*/, CS, *this,
14202  *DSAStack, VarsWithImplicitDSA, B);
14203  if (NestedLoopCount == 0)
14204  return StmtError();
14205 
14206  assert((CurContext->isDependentContext() || B.builtAll()) &&
14207  "omp teams distribute loop exprs were not built");
14208 
14210 
14211  DSAStack->setParentTeamsRegionLoc(StartLoc);
14212 
14214  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14215 }
14216 
14218  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14219  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14220  if (!AStmt)
14221  return StmtError();
14222 
14223  auto *CS = cast<CapturedStmt>(AStmt);
14224  // 1.2.2 OpenMP Language Terminology
14225  // Structured block - An executable statement with a single entry at the
14226  // top and a single exit at the bottom.
14227  // The point of exit cannot be a branch out of the structured block.
14228  // longjmp() and throw() must not violate the entry/exit criteria.
14229  CS->getCapturedDecl()->setNothrow();
14230  for (int ThisCaptureLevel =
14231  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14232  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14233  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14234  // 1.2.2 OpenMP Language Terminology
14235  // Structured block - An executable statement with a single entry at the
14236  // top and a single exit at the bottom.
14237  // The point of exit cannot be a branch out of the structured block.
14238  // longjmp() and throw() must not violate the entry/exit criteria.
14239  CS->getCapturedDecl()->setNothrow();
14240  }
14241 
14243  // In presence of clause 'collapse' with number of loops, it will
14244  // define the nested loops number.
14245  unsigned NestedLoopCount = checkOpenMPLoop(
14246  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14247  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14248  VarsWithImplicitDSA, B);
14249 
14250  if (NestedLoopCount == 0)
14251  return StmtError();
14252 
14253  assert((CurContext->isDependentContext() || B.builtAll()) &&
14254  "omp teams distribute simd loop exprs were not built");
14255 
14256  if (!CurContext->isDependentContext()) {
14257  // Finalize the clauses that need pre-built expressions for CodeGen.
14258  for (OMPClause *C : Clauses) {
14259  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14260  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14261  B.NumIterations, *this, CurScope,
14262  DSAStack))
14263  return StmtError();
14264  }
14265  }
14266 
14267  if (checkSimdlenSafelenSpecified(*this, Clauses))
14268  return StmtError();
14269 
14271 
14272  DSAStack->setParentTeamsRegionLoc(StartLoc);
14273 
14275  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14276 }
14277 
14279  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14280  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14281  if (!AStmt)
14282  return StmtError();
14283 
14284  auto *CS = cast<CapturedStmt>(AStmt);
14285  // 1.2.2 OpenMP Language Terminology
14286  // Structured block - An executable statement with a single entry at the
14287  // top and a single exit at the bottom.
14288  // The point of exit cannot be a branch out of the structured block.
14289  // longjmp() and throw() must not violate the entry/exit criteria.
14290  CS->getCapturedDecl()->setNothrow();
14291 
14292  for (int ThisCaptureLevel =
14293  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14294  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14295  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14296  // 1.2.2 OpenMP Language Terminology
14297  // Structured block - An executable statement with a single entry at the
14298  // top and a single exit at the bottom.
14299  // The point of exit cannot be a branch out of the structured block.
14300  // longjmp() and throw() must not violate the entry/exit criteria.
14301  CS->getCapturedDecl()->setNothrow();
14302  }
14303 
14305  // In presence of clause 'collapse' with number of loops, it will
14306  // define the nested loops number.
14307  unsigned NestedLoopCount = checkOpenMPLoop(
14308  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14309  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14310  VarsWithImplicitDSA, B);
14311 
14312  if (NestedLoopCount == 0)
14313  return StmtError();
14314 
14315  assert((CurContext->isDependentContext() || B.builtAll()) &&
14316  "omp for loop exprs were not built");
14317 
14318  if (!CurContext->isDependentContext()) {
14319  // Finalize the clauses that need pre-built expressions for CodeGen.
14320  for (OMPClause *C : Clauses) {
14321  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14322  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14323  B.NumIterations, *this, CurScope,
14324  DSAStack))
14325  return StmtError();
14326  }
14327  }
14328 
14329  if (checkSimdlenSafelenSpecified(*this, Clauses))
14330  return StmtError();
14331 
14333 
14334  DSAStack->setParentTeamsRegionLoc(StartLoc);
14335 
14337  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14338 }
14339 
14341  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14342  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14343  if (!AStmt)
14344  return StmtError();
14345 
14346  auto *CS = cast<CapturedStmt>(AStmt);
14347  // 1.2.2 OpenMP Language Terminology
14348  // Structured block - An executable statement with a single entry at the
14349  // top and a single exit at the bottom.
14350  // The point of exit cannot be a branch out of the structured block.
14351  // longjmp() and throw() must not violate the entry/exit criteria.
14352  CS->getCapturedDecl()->setNothrow();
14353 
14354  for (int ThisCaptureLevel =
14355  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14356  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14357  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14358  // 1.2.2 OpenMP Language Terminology
14359  // Structured block - An executable statement with a single entry at the
14360  // top and a single exit at the bottom.
14361  // The point of exit cannot be a branch out of the structured block.
14362  // longjmp() and throw() must not violate the entry/exit criteria.
14363  CS->getCapturedDecl()->setNothrow();
14364  }
14365 
14367  // In presence of clause 'collapse' with number of loops, it will
14368  // define the nested loops number.
14369  unsigned NestedLoopCount = checkOpenMPLoop(
14370  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14371  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14372  VarsWithImplicitDSA, B);
14373 
14374  if (NestedLoopCount == 0)
14375  return StmtError();
14376 
14377  assert((CurContext->isDependentContext() || B.builtAll()) &&
14378  "omp for loop exprs were not built");
14379 
14381 
14382  DSAStack->setParentTeamsRegionLoc(StartLoc);
14383 
14385  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14386  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14387 }
14388 
14390  Stmt *AStmt,
14391  SourceLocation StartLoc,
14392  SourceLocation EndLoc) {
14393  if (!AStmt)
14394  return StmtError();
14395 
14396  auto *CS = cast<CapturedStmt>(AStmt);
14397  // 1.2.2 OpenMP Language Terminology
14398  // Structured block - An executable statement with a single entry at the
14399  // top and a single exit at the bottom.
14400  // The point of exit cannot be a branch out of the structured block.
14401  // longjmp() and throw() must not violate the entry/exit criteria.
14402  CS->getCapturedDecl()->setNothrow();
14403 
14404  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14405  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14406  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14407  // 1.2.2 OpenMP Language Terminology
14408  // Structured block - An executable statement with a single entry at the
14409  // top and a single exit at the bottom.
14410  // The point of exit cannot be a branch out of the structured block.
14411  // longjmp() and throw() must not violate the entry/exit criteria.
14412  CS->getCapturedDecl()->setNothrow();
14413  }
14415 
14416  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14417  AStmt);
14418 }
14419 
14421  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14422  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14423  if (!AStmt)
14424  return StmtError();
14425 
14426  auto *CS = cast<CapturedStmt>(AStmt);
14427  // 1.2.2 OpenMP Language Terminology
14428  // Structured block - An executable statement with a single entry at the
14429  // top and a single exit at the bottom.
14430  // The point of exit cannot be a branch out of the structured block.
14431  // longjmp() and throw() must not violate the entry/exit criteria.
14432  CS->getCapturedDecl()->setNothrow();
14433  for (int ThisCaptureLevel =
14434  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14435  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14436  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14437  // 1.2.2 OpenMP Language Terminology
14438  // Structured block - An executable statement with a single entry at the
14439  // top and a single exit at the bottom.
14440  // The point of exit cannot be a branch out of the structured block.
14441  // longjmp() and throw() must not violate the entry/exit criteria.
14442  CS->getCapturedDecl()->setNothrow();
14443  }
14444 
14446  // In presence of clause 'collapse' with number of loops, it will
14447  // define the nested loops number.
14448  unsigned NestedLoopCount = checkOpenMPLoop(
14449  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14450  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14451  VarsWithImplicitDSA, B);
14452  if (NestedLoopCount == 0)
14453  return StmtError();
14454 
14455  assert((CurContext->isDependentContext() || B.builtAll()) &&
14456  "omp target teams distribute loop exprs were not built");
14457 
14460  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14461 }
14462 
14464  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14465  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14466  if (!AStmt)
14467  return StmtError();
14468 
14469  auto *CS = cast<CapturedStmt>(AStmt);
14470  // 1.2.2 OpenMP Language Terminology
14471  // Structured block - An executable statement with a single entry at the
14472  // top and a single exit at the bottom.
14473  // The point of exit cannot be a branch out of the structured block.
14474  // longjmp() and throw() must not violate the entry/exit criteria.
14475  CS->getCapturedDecl()->setNothrow();
14476  for (int ThisCaptureLevel =
14477  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14478  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14479  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14480  // 1.2.2 OpenMP Language Terminology
14481  // Structured block - An executable statement with a single entry at the
14482  // top and a single exit at the bottom.
14483  // The point of exit cannot be a branch out of the structured block.
14484  // longjmp() and throw() must not violate the entry/exit criteria.
14485  CS->getCapturedDecl()->setNothrow();
14486  }
14487 
14489  // In presence of clause 'collapse' with number of loops, it will
14490  // define the nested loops number.
14491  unsigned NestedLoopCount = checkOpenMPLoop(
14492  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14493  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14494  VarsWithImplicitDSA, B);
14495  if (NestedLoopCount == 0)
14496  return StmtError();
14497 
14498  assert((CurContext->isDependentContext() || B.builtAll()) &&
14499  "omp target teams distribute parallel for loop exprs were not built");
14500 
14501  if (!CurContext->isDependentContext()) {
14502  // Finalize the clauses that need pre-built expressions for CodeGen.
14503  for (OMPClause *C : Clauses) {
14504  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14505  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14506  B.NumIterations, *this, CurScope,
14507  DSAStack))
14508  return StmtError();
14509  }
14510  }
14511 
14514  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14515  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14516 }
14517 
14519  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14520  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14521  if (!AStmt)
14522  return StmtError();
14523 
14524  auto *CS = cast<CapturedStmt>(AStmt);
14525  // 1.2.2 OpenMP Language Terminology
14526  // Structured block - An executable statement with a single entry at the
14527  // top and a single exit at the bottom.
14528  // The point of exit cannot be a branch out of the structured block.
14529  // longjmp() and throw() must not violate the entry/exit criteria.
14530  CS->getCapturedDecl()->setNothrow();
14531  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14532  OMPD_target_teams_distribute_parallel_for_simd);
14533  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14534  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14535  // 1.2.2 OpenMP Language Terminology
14536  // Structured block - An executable statement with a single entry at the
14537  // top and a single exit at the bottom.
14538  // The point of exit cannot be a branch out of the structured block.
14539  // longjmp() and throw() must not violate the entry/exit criteria.
14540  CS->getCapturedDecl()->setNothrow();
14541  }
14542 
14544  // In presence of clause 'collapse' with number of loops, it will
14545  // define the nested loops number.
14546  unsigned NestedLoopCount =
14547  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14548  getCollapseNumberExpr(Clauses),
14549  nullptr /*ordered not a clause on distribute*/, CS, *this,
14550  *DSAStack, VarsWithImplicitDSA, B);
14551  if (NestedLoopCount == 0)
14552  return StmtError();
14553 
14554  assert((CurContext->isDependentContext() || B.builtAll()) &&
14555  "omp target teams distribute parallel for simd loop exprs were not "
14556  "built");
14557 
14558  if (!CurContext->isDependentContext()) {
14559  // Finalize the clauses that need pre-built expressions for CodeGen.
14560  for (OMPClause *C : Clauses) {
14561  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14562  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14563  B.NumIterations, *this, CurScope,
14564  DSAStack))
14565  return StmtError();
14566  }
14567  }
14568 
14569  if (checkSimdlenSafelenSpecified(*this, Clauses))
14570  return StmtError();
14571 
14574  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14575 }
14576 
14578  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14579  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14580  if (!AStmt)
14581  return StmtError();
14582 
14583  auto *CS = cast<CapturedStmt>(AStmt);
14584  // 1.2.2 OpenMP Language Terminology
14585  // Structured block - An executable statement with a single entry at the
14586  // top and a single exit at the bottom.
14587  // The point of exit cannot be a branch out of the structured block.
14588  // longjmp() and throw() must not violate the entry/exit criteria.
14589  CS->getCapturedDecl()->setNothrow();
14590  for (int ThisCaptureLevel =
14591  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14592  ThisCaptureLevel > 1; --ThisCaptureLevel) {
14593  CS = cast<CapturedStmt>(CS->getCapturedStmt());
14594  // 1.2.2 OpenMP Language Terminology
14595  // Structured block - An executable statement with a single entry at the
14596  // top and a single exit at the bottom.
14597  // The point of exit cannot be a branch out of the structured block.
14598  // longjmp() and throw() must not violate the entry/exit criteria.
14599  CS->getCapturedDecl()->setNothrow();
14600  }
14601 
14603  // In presence of clause 'collapse' with number of loops, it will
14604  // define the nested loops number.
14605  unsigned NestedLoopCount = checkOpenMPLoop(
14606  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14607  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14608  VarsWithImplicitDSA, B);
14609  if (NestedLoopCount == 0)
14610  return StmtError();
14611 
14612  assert((CurContext->isDependentContext() || B.builtAll()) &&
14613  "omp target teams distribute simd loop exprs were not built");
14614 
14615  if (!CurContext->isDependentContext()) {
14616  // Finalize the clauses that need pre-built expressions for CodeGen.
14617  for (OMPClause *C : Clauses) {
14618  if (auto *LC = dyn_cast<OMPLinearClause>(C))
14619  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14620  B.NumIterations, *this, CurScope,
14621  DSAStack))
14622  return StmtError();
14623  }
14624  }
14625 
14626  if (checkSimdlenSafelenSpecified(*this, Clauses))
14627  return StmtError();
14628 
14631  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14632 }
14633 
14634 bool Sema::checkTransformableLoopNest(
14635  OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14637  Stmt *&Body,
14638  SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14639  &OriginalInits) {
14640  OriginalInits.emplace_back();
14642  AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14643  [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14644  Stmt *CurStmt) {
14645  VarsWithInheritedDSAType TmpDSA;
14646  unsigned SingleNumLoops =
14647  checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14648  TmpDSA, LoopHelpers[Cnt]);
14649  if (SingleNumLoops == 0)
14650  return true;
14651  assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14652  if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14653  OriginalInits.back().push_back(For->getInit());
14654  Body = For->getBody();
14655  } else {
14656  assert(isa<CXXForRangeStmt>(CurStmt) &&
14657  "Expected canonical for or range-based for loops.");
14658  auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14659  OriginalInits.back().push_back(CXXFor->getBeginStmt());
14660  Body = CXXFor->getBody();
14661  }
14662  OriginalInits.emplace_back();
14663  return false;
14664  },
14665  [&OriginalInits](OMPLoopBasedDirective *Transform) {
14666  Stmt *DependentPreInits;
14667  if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14668  DependentPreInits = Dir->getPreInits();
14669  else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14670  DependentPreInits = Dir->getPreInits();
14671  else
14672  llvm_unreachable("Unhandled loop transformation");
14673  if (!DependentPreInits)
14674  return;
14675  llvm::append_range(OriginalInits.back(),
14676  cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14677  });
14678  assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14679  OriginalInits.pop_back();
14680  return Result;
14681 }
14682 
14684  Stmt *AStmt, SourceLocation StartLoc,
14685  SourceLocation EndLoc) {
14686  auto SizesClauses =
14687  OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14688  if (SizesClauses.empty()) {
14689  // A missing 'sizes' clause is already reported by the parser.
14690  return StmtError();
14691  }
14692  const OMPSizesClause *SizesClause = *SizesClauses.begin();
14693  unsigned NumLoops = SizesClause->getNumSizes();
14694 
14695  // Empty statement should only be possible if there already was an error.
14696  if (!AStmt)
14697  return StmtError();
14698 
14699  // Verify and diagnose loop nest.
14701  Stmt *Body = nullptr;
14703  OriginalInits;
14704  if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14705  OriginalInits))
14706  return StmtError();
14707 
14708  // Delay tiling to when template is completely instantiated.
14710  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14711  NumLoops, AStmt, nullptr, nullptr);
14712 
14713  SmallVector<Decl *, 4> PreInits;
14714 
14715  // Create iteration variables for the generated loops.
14716  SmallVector<VarDecl *, 4> FloorIndVars;
14717  SmallVector<VarDecl *, 4> TileIndVars;
14718  FloorIndVars.resize(NumLoops);
14719  TileIndVars.resize(NumLoops);
14720  for (unsigned I = 0; I < NumLoops; ++I) {
14721  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14722 
14723  assert(LoopHelper.Counters.size() == 1 &&
14724  "Expect single-dimensional loop iteration space");
14725  auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14726  std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14727  DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14728  QualType CntTy = IterVarRef->getType();
14729 
14730  // Iteration variable for the floor (i.e. outer) loop.
14731  {
14732  std::string FloorCntName =
14733  (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14734  VarDecl *FloorCntDecl =
14735  buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14736  FloorIndVars[I] = FloorCntDecl;
14737  }
14738 
14739  // Iteration variable for the tile (i.e. inner) loop.
14740  {
14741  std::string TileCntName =
14742  (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14743 
14744  // Reuse the iteration variable created by checkOpenMPLoop. It is also
14745  // used by the expressions to derive the original iteration variable's
14746  // value from the logical iteration number.
14747  auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14748  TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14749  TileIndVars[I] = TileCntDecl;
14750  }
14751  for (auto &P : OriginalInits[I]) {
14752  if (auto *D = P.dyn_cast<Decl *>())
14753  PreInits.push_back(D);
14754  else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14755  PreInits.append(PI->decl_begin(), PI->decl_end());
14756  }
14757  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14758  PreInits.append(PI->decl_begin(), PI->decl_end());
14759  // Gather declarations for the data members used as counters.
14760  for (Expr *CounterRef : LoopHelper.Counters) {
14761  auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14762  if (isa<OMPCapturedExprDecl>(CounterDecl))
14763  PreInits.push_back(CounterDecl);
14764  }
14765  }
14766 
14767  // Once the original iteration values are set, append the innermost body.
14768  Stmt *Inner = Body;
14769 
14770  // Create tile loops from the inside to the outside.
14771  for (int I = NumLoops - 1; I >= 0; --I) {
14772  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14773  Expr *NumIterations = LoopHelper.NumIterations;
14774  auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14775  QualType CntTy = OrigCntVar->getType();
14776  Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14777  Scope *CurScope = getCurScope();
14778 
14779  // Commonly used variables.
14780  DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14781  OrigCntVar->getExprLoc());
14782  DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14783  OrigCntVar->getExprLoc());
14784 
14785  // For init-statement: auto .tile.iv = .floor.iv
14786  AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14787  /*DirectInit=*/false);
14788  Decl *CounterDecl = TileIndVars[I];
14789  StmtResult InitStmt = new (Context)
14790  DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14791  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14792  if (!InitStmt.isUsable())
14793  return StmtError();
14794 
14795  // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14796  // NumIterations)
14797  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14798  BO_Add, FloorIV, DimTileSize);
14799  if (!EndOfTile.isUsable())
14800  return StmtError();
14801  ExprResult IsPartialTile =
14802  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14803  NumIterations, EndOfTile.get());
14804  if (!IsPartialTile.isUsable())
14805  return StmtError();
14806  ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14807  LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14808  IsPartialTile.get(), NumIterations, EndOfTile.get());
14809  if (!MinTileAndIterSpace.isUsable())
14810  return StmtError();
14811  ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14812  BO_LT, TileIV, MinTileAndIterSpace.get());
14813  if (!CondExpr.isUsable())
14814  return StmtError();
14815 
14816  // For incr-statement: ++.tile.iv
14817  ExprResult IncrStmt =
14818  BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14819  if (!IncrStmt.isUsable())
14820  return StmtError();
14821 
14822  // Statements to set the original iteration variable's value from the
14823  // logical iteration number.
14824  // Generated for loop is:
14825  // Original_for_init;
14826  // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14827  // NumIterations); ++.tile.iv) {
14828  // Original_Body;
14829  // Original_counter_update;
14830  // }
14831  // FIXME: If the innermost body is an loop itself, inserting these
14832  // statements stops it being recognized as a perfectly nested loop (e.g.
14833  // for applying tiling again). If this is the case, sink the expressions
14834  // further into the inner loop.
14835  SmallVector<Stmt *, 4> BodyParts;
14836  BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14837  BodyParts.push_back(Inner);
14838  Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
14839  Inner->getBeginLoc(), Inner->getEndLoc());
14840  Inner = new (Context)
14841  ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14842  IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14843  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14844  }
14845 
14846  // Create floor loops from the inside to the outside.
14847  for (int I = NumLoops - 1; I >= 0; --I) {
14848  auto &LoopHelper = LoopHelpers[I];
14849  Expr *NumIterations = LoopHelper.NumIterations;
14850  DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14851  QualType CntTy = OrigCntVar->getType();
14852  Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14853  Scope *CurScope = getCurScope();
14854 
14855  // Commonly used variables.
14856  DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14857  OrigCntVar->getExprLoc());
14858 
14859  // For init-statement: auto .floor.iv = 0
14861  FloorIndVars[I],
14862  ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14863  /*DirectInit=*/false);
14864  Decl *CounterDecl = FloorIndVars[I];
14865  StmtResult InitStmt = new (Context)
14866  DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14867  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14868  if (!InitStmt.isUsable())
14869  return StmtError();
14870 
14871  // For cond-expression: .floor.iv < NumIterations
14872  ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14873  BO_LT, FloorIV, NumIterations);
14874  if (!CondExpr.isUsable())
14875  return StmtError();
14876 
14877  // For incr-statement: .floor.iv += DimTileSize
14878  ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14879  BO_AddAssign, FloorIV, DimTileSize);
14880  if (!IncrStmt.isUsable())
14881  return StmtError();
14882 
14883  Inner = new (Context)
14884  ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14885  IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14886  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14887  }
14888 
14889  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14890  AStmt, Inner,
14891  buildPreInits(Context, PreInits));
14892 }
14893 
14895  Stmt *AStmt,
14896  SourceLocation StartLoc,
14897  SourceLocation EndLoc) {
14898  // Empty statement should only be possible if there already was an error.
14899  if (!AStmt)
14900  return StmtError();
14901 
14902  if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14903  return StmtError();
14904 
14905  const OMPFullClause *FullClause =
14906  OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14907  const OMPPartialClause *PartialClause =
14908  OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14909  assert(!(FullClause && PartialClause) &&
14910  "mutual exclusivity must have been checked before");
14911 
14912  constexpr unsigned NumLoops = 1;
14913  Stmt *Body = nullptr;
14915  NumLoops);
14917  OriginalInits;
14918  if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14919  Body, OriginalInits))
14920  return StmtError();
14921 
14922  unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14923 
14924  // Delay unrolling to when template is completely instantiated.
14926  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14927  NumGeneratedLoops, nullptr, nullptr);
14928 
14929  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14930 
14931  if (FullClause) {
14932  if (!VerifyPositiveIntegerConstantInClause(
14933  LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14934  /*SuppressExprDiags=*/true)
14935  .isUsable()) {
14936  Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14937  Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14938  << "#pragma omp unroll full";
14939  return StmtError();
14940  }
14941  }
14942 
14943  // The generated loop may only be passed to other loop-associated directive
14944  // when a partial clause is specified. Without the requirement it is
14945  // sufficient to generate loop unroll metadata at code-generation.
14946  if (NumGeneratedLoops == 0)
14947  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14948  NumGeneratedLoops, nullptr, nullptr);
14949 
14950  // Otherwise, we need to provide a de-sugared/transformed AST that can be
14951  // associated with another loop directive.
14952  //
14953  // The canonical loop analysis return by checkTransformableLoopNest assumes
14954  // the following structure to be the same loop without transformations or
14955  // directives applied: \code OriginalInits; LoopHelper.PreInits;
14956  // LoopHelper.Counters;
14957  // for (; IV < LoopHelper.NumIterations; ++IV) {
14958  // LoopHelper.Updates;
14959  // Body;
14960  // }
14961  // \endcode
14962  // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14963  // and referenced by LoopHelper.IterationVarRef.
14964  //
14965  // The unrolling directive transforms this into the following loop:
14966  // \code
14967  // OriginalInits; \
14968  // LoopHelper.PreInits; > NewPreInits
14969  // LoopHelper.Counters; /
14970  // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14971  // #pragma clang loop unroll_count(Factor)
14972  // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14973  // {
14974  // LoopHelper.Updates;
14975  // Body;
14976  // }
14977  // }
14978  // \endcode
14979  // where UIV is a new logical iteration counter. IV must be the same VarDecl
14980  // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14981  // references it. If the partially unrolled loop is associated with another
14982  // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14983  // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14984  // OpenMP canonical loop. The inner loop is not an associable canonical loop
14985  // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14986  // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14987  // property of the OMPLoopBasedDirective instead of statements in
14988  // CompoundStatement. This is to allow the loop to become a non-outermost loop
14989  // of a canonical loop nest where these PreInits are emitted before the
14990  // outermost directive.
14991 
14992  // Determine the PreInit declarations.
14993  SmallVector<Decl *, 4> PreInits;
14994  assert(OriginalInits.size() == 1 &&
14995  "Expecting a single-dimensional loop iteration space");
14996  for (auto &P : OriginalInits[0]) {
14997  if (auto *D = P.dyn_cast<Decl *>())
14998  PreInits.push_back(D);
14999  else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15000  PreInits.append(PI->decl_begin(), PI->decl_end());
15001  }
15002  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15003  PreInits.append(PI->decl_begin(), PI->decl_end());
15004  // Gather declarations for the data members used as counters.
15005  for (Expr *CounterRef : LoopHelper.Counters) {
15006  auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15007  if (isa<OMPCapturedExprDecl>(CounterDecl))
15008  PreInits.push_back(CounterDecl);
15009  }
15010 
15011  auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15012  QualType IVTy = IterationVarRef->getType();
15013  assert(LoopHelper.Counters.size() == 1 &&
15014  "Expecting a single-dimensional loop iteration space");
15015  auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15016 
15017  // Determine the unroll factor.
15018  uint64_t Factor;
15019  SourceLocation FactorLoc;
15020  if (Expr *FactorVal = PartialClause->getFactor()) {
15021  Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15022  FactorLoc = FactorVal->getExprLoc();
15023  } else {
15024  // TODO: Use a better profitability model.
15025  Factor = 2;
15026  }
15027  assert(Factor > 0 && "Expected positive unroll factor");
15028  auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
15029  return IntegerLiteral::Create(
15030  Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15031  FactorLoc);
15032  };
15033 
15034  // Iteration variable SourceLocations.
15035  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15036  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15037  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15038 
15039  // Internal variable names.
15040  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15041  std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15042  std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15043  std::string InnerTripCountName =
15044  (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15045 
15046  // Create the iteration variable for the unrolled loop.
15047  VarDecl *OuterIVDecl =
15048  buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15049  auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15050  return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15051  };
15052 
15053  // Iteration variable for the inner loop: Reuse the iteration variable created
15054  // by checkOpenMPLoop.
15055  auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15056  InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15057  auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15058  return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15059  };
15060 
15061  // Make a copy of the NumIterations expression for each use: By the AST
15062  // constraints, every expression object in a DeclContext must be unique.
15063  CaptureVars CopyTransformer(*this);
15064  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15065  return AssertSuccess(
15066  CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15067  };
15068 
15069  // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15070  ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15071  AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15072  StmtResult InnerInit = new (Context)
15073  DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15074  if (!InnerInit.isUsable())
15075  return StmtError();
15076 
15077  // Inner For cond-expression:
15078  // \code
15079  // .unroll_inner.iv < .unrolled.iv + Factor &&
15080  // .unroll_inner.iv < NumIterations
15081  // \endcode
15082  // This conjunction of two conditions allows ScalarEvolution to derive the
15083  // maximum trip count of the inner loop.
15084  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15085  BO_Add, MakeOuterRef(), MakeFactorExpr());
15086  if (!EndOfTile.isUsable())
15087  return StmtError();
15088  ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15089  BO_LT, MakeInnerRef(), EndOfTile.get());
15090  if (!InnerCond1.isUsable())
15091  return StmtError();
15092  ExprResult InnerCond2 =
15093  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15094  MakeNumIterations());
15095  if (!InnerCond2.isUsable())
15096  return StmtError();
15097  ExprResult InnerCond =
15098  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15099  InnerCond1.get(), InnerCond2.get());
15100  if (!InnerCond.isUsable())
15101  return StmtError();
15102 
15103  // Inner For incr-statement: ++.unroll_inner.iv
15104  ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15105  UO_PreInc, MakeInnerRef());
15106  if (!InnerIncr.isUsable())
15107  return StmtError();
15108 
15109  // Inner For statement.
15110  SmallVector<Stmt *> InnerBodyStmts;
15111  InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15112  InnerBodyStmts.push_back(Body);
15113  CompoundStmt *InnerBody =
15114  CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15115  Body->getBeginLoc(), Body->getEndLoc());
15116  ForStmt *InnerFor = new (Context)
15117  ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15118  InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15119  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15120 
15121  // Unroll metadata for the inner loop.
15122  // This needs to take into account the remainder portion of the unrolled loop,
15123  // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15124  // supports multiple loop exits. Instead, unroll using a factor equivalent to
15125  // the maximum trip count, which will also generate a remainder loop. Just
15126  // `unroll(enable)` (which could have been useful if the user has not
15127  // specified a concrete factor; even though the outer loop cannot be
15128  // influenced anymore, would avoid more code bloat than necessary) will refuse
15129  // the loop because "Won't unroll; remainder loop could not be generated when
15130  // assuming runtime trip count". Even if it did work, it must not choose a
15131  // larger unroll factor than the maximum loop length, or it would always just
15132  // execute the remainder loop.
15133  LoopHintAttr *UnrollHintAttr =
15134  LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15135  LoopHintAttr::Numeric, MakeFactorExpr());
15136  AttributedStmt *InnerUnrolled =
15137  AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15138 
15139  // Outer For init-statement: auto .unrolled.iv = 0
15141  OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15142  /*DirectInit=*/false);
15143  StmtResult OuterInit = new (Context)
15144  DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15145  if (!OuterInit.isUsable())
15146  return StmtError();
15147 
15148  // Outer For cond-expression: .unrolled.iv < NumIterations
15149  ExprResult OuterConde =
15150  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15151  MakeNumIterations());
15152  if (!OuterConde.isUsable())
15153  return StmtError();
15154 
15155  // Outer For incr-statement: .unrolled.iv += Factor
15156  ExprResult OuterIncr =
15157  BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15158  MakeOuterRef(), MakeFactorExpr());
15159  if (!OuterIncr.isUsable())
15160  return StmtError();
15161 
15162  // Outer For statement.
15163  ForStmt *OuterFor = new (Context)
15164  ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15165  OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15166  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15167 
15168  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15169  NumGeneratedLoops, OuterFor,
15170  buildPreInits(Context, PreInits));
15171 }
15172 
15174  SourceLocation StartLoc,
15175  SourceLocation LParenLoc,
15176  SourceLocation EndLoc) {
15177  OMPClause *Res = nullptr;
15178  switch (Kind) {
15179  case OMPC_final:
15180  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15181  break;
15182  case OMPC_num_threads:
15183  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15184  break;
15185  case OMPC_safelen:
15186  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15187  break;
15188  case OMPC_simdlen:
15189  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15190  break;
15191  case OMPC_allocator:
15192  Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15193  break;
15194  case OMPC_collapse:
15195  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15196  break;
15197  case OMPC_ordered:
15198  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15199  break;
15200  case OMPC_num_teams:
15201  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15202  break;
15203  case OMPC_thread_limit:
15204  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15205  break;
15206  case OMPC_priority:
15207  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15208  break;
15209  case OMPC_hint:
15210  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15211  break;
15212  case OMPC_depobj:
15213  Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15214  break;
15215  case OMPC_detach:
15216  Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15217  break;
15218  case OMPC_novariants:
15219  Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15220  break;
15221  case OMPC_nocontext:
15222  Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15223  break;
15224  case OMPC_filter:
15225  Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15226  break;
15227  case OMPC_partial:
15228  Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15229  break;
15230  case OMPC_message:
15231  Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15232  break;
15233  case OMPC_align:
15234  Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15235  break;
15236  case OMPC_ompx_dyn_cgroup_mem:
15237  Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15238  break;
15239  case OMPC_grainsize:
15240  case OMPC_num_tasks:
15241  case OMPC_device:
15242  case OMPC_if:
15243  case OMPC_default:
15244  case OMPC_proc_bind:
15245  case OMPC_schedule:
15246  case OMPC_private:
15247  case OMPC_firstprivate:
15248  case OMPC_lastprivate:
15249  case OMPC_shared:
15250  case OMPC_reduction:
15251  case OMPC_task_reduction:
15252  case OMPC_in_reduction:
15253  case OMPC_linear:
15254  case OMPC_aligned:
15255  case OMPC_copyin:
15256  case OMPC_copyprivate:
15257  case OMPC_nowait:
15258  case OMPC_untied:
15259  case OMPC_mergeable:
15260  case OMPC_threadprivate:
15261  case OMPC_sizes:
15262  case OMPC_allocate:
15263  case OMPC_flush:
15264  case OMPC_read:
15265  case OMPC_write:
15266  case OMPC_update:
15267  case OMPC_capture:
15268  case OMPC_compare:
15269  case OMPC_seq_cst:
15270  case OMPC_acq_rel:
15271  case OMPC_acquire:
15272  case OMPC_release:
15273  case OMPC_relaxed:
15274  case OMPC_depend:
15275  case OMPC_threads:
15276  case OMPC_simd:
15277  case OMPC_map:
15278  case OMPC_nogroup:
15279  case OMPC_dist_schedule:
15280  case OMPC_defaultmap:
15281  case OMPC_unknown:
15282  case OMPC_uniform:
15283  case OMPC_to:
15284  case OMPC_from:
15285  case OMPC_use_device_ptr:
15286  case OMPC_use_device_addr:
15287  case OMPC_is_device_ptr:
15288  case OMPC_unified_address:
15289  case OMPC_unified_shared_memory:
15290  case OMPC_reverse_offload:
15291  case OMPC_dynamic_allocators:
15292  case OMPC_atomic_default_mem_order:
15293  case OMPC_device_type:
15294  case OMPC_match:
15295  case OMPC_nontemporal:
15296  case OMPC_order:
15297  case OMPC_at:
15298  case OMPC_severity:
15299  case OMPC_destroy:
15300  case OMPC_inclusive:
15301  case OMPC_exclusive:
15302  case OMPC_uses_allocators:
15303  case OMPC_affinity:
15304  case OMPC_when:
15305  case OMPC_bind:
15306  default:
15307  llvm_unreachable("Clause is not allowed.");
15308  }
15309  return Res;
15310 }
15311 
15312 // An OpenMP directive such as 'target parallel' has two captured regions:
15313 // for the 'target' and 'parallel' respectively. This function returns
15314 // the region in which to capture expressions associated with a clause.
15315 // A return value of OMPD_unknown signifies that the expression should not
15316 // be captured.
15318  OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15319  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15320  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15321  switch (CKind) {
15322  case OMPC_if:
15323  switch (DKind) {
15324  case OMPD_target_parallel_for_simd:
15325  if (OpenMPVersion >= 50 &&
15326  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15327  CaptureRegion = OMPD_parallel;
15328  break;
15329  }
15330  [[fallthrough]];
15331  case OMPD_target_parallel:
15332  case OMPD_target_parallel_for:
15333  case OMPD_target_parallel_loop:
15334  // If this clause applies to the nested 'parallel' region, capture within
15335  // the 'target' region, otherwise do not capture.
15336  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15337  CaptureRegion = OMPD_target;
15338  break;
15339  case OMPD_target_teams_distribute_parallel_for_simd:
15340  if (OpenMPVersion >= 50 &&
15341  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15342  CaptureRegion = OMPD_parallel;
15343  break;
15344  }
15345  [[fallthrough]];
15346  case OMPD_target_teams_distribute_parallel_for:
15347  // If this clause applies to the nested 'parallel' region, capture within
15348  // the 'teams' region, otherwise do not capture.
15349  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15350  CaptureRegion = OMPD_teams;
15351  break;
15352  case OMPD_teams_distribute_parallel_for_simd:
15353  if (OpenMPVersion >= 50 &&
15354  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15355  CaptureRegion = OMPD_parallel;
15356  break;
15357  }
15358  [[fallthrough]];
15359  case OMPD_teams_distribute_parallel_for:
15360  CaptureRegion = OMPD_teams;
15361  break;
15362  case OMPD_target_update:
15363  case OMPD_target_enter_data:
15364  case OMPD_target_exit_data:
15365  CaptureRegion = OMPD_task;
15366  break;
15367  case OMPD_parallel_masked_taskloop:
15368  if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15369  CaptureRegion = OMPD_parallel;
15370  break;
15371  case OMPD_parallel_master_taskloop:
15372  if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15373  CaptureRegion = OMPD_parallel;
15374  break;
15375  case OMPD_parallel_masked_taskloop_simd:
15376  if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15377  NameModifier == OMPD_taskloop) {
15378  CaptureRegion = OMPD_parallel;
15379  break;
15380  }
15381  if (OpenMPVersion <= 45)
15382  break;
15383  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15384  CaptureRegion = OMPD_taskloop;
15385  break;
15386  case OMPD_parallel_master_taskloop_simd:
15387  if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15388  NameModifier == OMPD_taskloop) {
15389  CaptureRegion = OMPD_parallel;
15390  break;
15391  }
15392  if (OpenMPVersion <= 45)
15393  break;
15394  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15395  CaptureRegion = OMPD_taskloop;
15396  break;
15397  case OMPD_parallel_for_simd:
15398  if (OpenMPVersion <= 45)
15399  break;
15400  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15401  CaptureRegion = OMPD_parallel;
15402  break;
15403  case OMPD_taskloop_simd:
15404  case OMPD_master_taskloop_simd:
15405  case OMPD_masked_taskloop_simd:
15406  if (OpenMPVersion <= 45)
15407  break;
15408  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15409  CaptureRegion = OMPD_taskloop;
15410  break;
15411  case OMPD_distribute_parallel_for_simd:
15412  if (OpenMPVersion <= 45)
15413  break;
15414  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15415  CaptureRegion = OMPD_parallel;
15416  break;
15417  case OMPD_target_simd:
15418  if (OpenMPVersion >= 50 &&
15419  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15420  CaptureRegion = OMPD_target;
15421  break;
15422  case OMPD_teams_distribute_simd:
15423  case OMPD_target_teams_distribute_simd:
15424  if (OpenMPVersion >= 50 &&
15425  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15426  CaptureRegion = OMPD_teams;
15427  break;
15428  case OMPD_cancel:
15429  case OMPD_parallel:
15430  case OMPD_parallel_master:
15431  case OMPD_parallel_masked:
15432  case OMPD_parallel_sections:
15433  case OMPD_parallel_for:
15434  case OMPD_parallel_loop:
15435  case OMPD_target:
15436  case OMPD_target_teams:
15437  case OMPD_target_teams_distribute:
15438  case OMPD_target_teams_loop:
15439  case OMPD_distribute_parallel_for:
15440  case OMPD_task:
15441  case OMPD_taskloop:
15442  case OMPD_master_taskloop:
15443  case OMPD_masked_taskloop:
15444  case OMPD_target_data:
15445  case OMPD_simd:
15446  case OMPD_for_simd:
15447  case OMPD_distribute_simd:
15448  // Do not capture if-clause expressions.
15449  break;
15450  case OMPD_threadprivate:
15451  case OMPD_allocate:
15452  case OMPD_taskyield:
15453  case OMPD_error:
15454  case OMPD_barrier:
15455  case OMPD_taskwait:
15456  case OMPD_cancellation_point:
15457  case OMPD_flush:
15458  case OMPD_depobj:
15459  case OMPD_scan:
15460  case OMPD_declare_reduction:
15461  case OMPD_declare_mapper:
15462  case OMPD_declare_simd:
15463  case OMPD_declare_variant:
15464  case OMPD_begin_declare_variant:
15465  case OMPD_end_declare_variant:
15466  case OMPD_declare_target:
15467  case OMPD_end_declare_target:
15468  case OMPD_loop:
15469  case OMPD_teams_loop:
15470  case OMPD_teams:
15471  case OMPD_tile:
15472  case OMPD_unroll:
15473  case OMPD_for:
15474  case OMPD_sections:
15475  case OMPD_section:
15476  case OMPD_single:
15477  case OMPD_master:
15478  case OMPD_masked:
15479  case OMPD_critical:
15480  case OMPD_taskgroup:
15481  case OMPD_distribute:
15482  case OMPD_ordered:
15483  case OMPD_atomic:
15484  case OMPD_teams_distribute:
15485  case OMPD_requires:
15486  case OMPD_metadirective:
15487  llvm_unreachable("Unexpected OpenMP directive with if-clause");
15488  case OMPD_unknown:
15489  default:
15490  llvm_unreachable("Unknown OpenMP directive");
15491  }
15492  break;
15493  case OMPC_num_threads:
15494  switch (DKind) {
15495  case OMPD_target_parallel:
15496  case OMPD_target_parallel_for:
15497  case OMPD_target_parallel_for_simd:
15498  case OMPD_target_parallel_loop:
15499  CaptureRegion = OMPD_target;
15500  break;
15501  case OMPD_teams_distribute_parallel_for:
15502  case OMPD_teams_distribute_parallel_for_simd:
15503  case OMPD_target_teams_distribute_parallel_for:
15504  case OMPD_target_teams_distribute_parallel_for_simd:
15505  CaptureRegion = OMPD_teams;
15506  break;
15507  case OMPD_parallel:
15508  case OMPD_parallel_master:
15509  case OMPD_parallel_masked:
15510  case OMPD_parallel_sections:
15511  case OMPD_parallel_for:
15512  case OMPD_parallel_for_simd:
15513  case OMPD_parallel_loop:
15514  case OMPD_distribute_parallel_for:
15515  case OMPD_distribute_parallel_for_simd:
15516  case OMPD_parallel_master_taskloop:
15517  case OMPD_parallel_masked_taskloop:
15518  case OMPD_parallel_master_taskloop_simd:
15519  case OMPD_parallel_masked_taskloop_simd:
15520  // Do not capture num_threads-clause expressions.
15521  break;
15522  case OMPD_target_data:
15523  case OMPD_target_enter_data:
15524  case OMPD_target_exit_data:
15525  case OMPD_target_update:
15526  case OMPD_target:
15527  case OMPD_target_simd:
15528  case OMPD_target_teams:
15529  case OMPD_target_teams_distribute:
15530  case OMPD_target_teams_distribute_simd:
15531  case OMPD_cancel:
15532  case OMPD_task:
15533  case OMPD_taskloop:
15534  case OMPD_taskloop_simd:
15535  case OMPD_master_taskloop:
15536  case OMPD_masked_taskloop:
15537  case OMPD_master_taskloop_simd:
15538  case OMPD_masked_taskloop_simd:
15539  case OMPD_threadprivate:
15540  case OMPD_allocate:
15541  case OMPD_taskyield:
15542  case OMPD_error:
15543  case OMPD_barrier:
15544  case OMPD_taskwait:
15545  case OMPD_cancellation_point:
15546  case OMPD_flush:
15547  case OMPD_depobj:
15548  case OMPD_scan:
15549  case OMPD_declare_reduction:
15550  case OMPD_declare_mapper:
15551  case OMPD_declare_simd:
15552  case OMPD_declare_variant:
15553  case OMPD_begin_declare_variant:
15554  case OMPD_end_declare_variant:
15555  case OMPD_declare_target:
15556  case OMPD_end_declare_target:
15557  case OMPD_loop:
15558  case OMPD_teams_loop:
15559  case OMPD_target_teams_loop:
15560  case OMPD_teams:
15561  case OMPD_simd:
15562  case OMPD_tile:
15563  case OMPD_unroll:
15564  case OMPD_for:
15565  case OMPD_for_simd:
15566  case OMPD_sections:
15567  case OMPD_section:
15568  case OMPD_single:
15569  case OMPD_master:
15570  case OMPD_masked:
15571  case OMPD_critical:
15572  case OMPD_taskgroup:
15573  case OMPD_distribute:
15574  case OMPD_ordered:
15575  case OMPD_atomic:
15576  case OMPD_distribute_simd:
15577  case OMPD_teams_distribute:
15578  case OMPD_teams_distribute_simd:
15579  case OMPD_requires:
15580  case OMPD_metadirective:
15581  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15582  case OMPD_unknown:
15583  default:
15584  llvm_unreachable("Unknown OpenMP directive");
15585  }
15586  break;
15587  case OMPC_num_teams:
15588  switch (DKind) {
15589  case OMPD_target_teams:
15590  case OMPD_target_teams_distribute:
15591  case OMPD_target_teams_distribute_simd:
15592  case OMPD_target_teams_distribute_parallel_for:
15593  case OMPD_target_teams_distribute_parallel_for_simd:
15594  case OMPD_target_teams_loop:
15595  CaptureRegion = OMPD_target;
15596  break;
15597  case OMPD_teams_distribute_parallel_for:
15598  case OMPD_teams_distribute_parallel_for_simd:
15599  case OMPD_teams:
15600  case OMPD_teams_distribute:
15601  case OMPD_teams_distribute_simd:
15602  case OMPD_teams_loop:
15603  // Do not capture num_teams-clause expressions.
15604  break;
15605  case OMPD_distribute_parallel_for:
15606  case OMPD_distribute_parallel_for_simd:
15607  case OMPD_task:
15608  case OMPD_taskloop:
15609  case OMPD_taskloop_simd:
15610  case OMPD_master_taskloop:
15611  case OMPD_masked_taskloop:
15612  case OMPD_master_taskloop_simd:
15613  case OMPD_masked_taskloop_simd:
15614  case OMPD_parallel_master_taskloop:
15615  case OMPD_parallel_masked_taskloop:
15616  case OMPD_parallel_master_taskloop_simd:
15617  case OMPD_parallel_masked_taskloop_simd:
15618  case OMPD_target_data:
15619  case OMPD_target_enter_data:
15620  case OMPD_target_exit_data:
15621  case OMPD_target_update:
15622  case OMPD_cancel:
15623  case OMPD_parallel:
15624  case OMPD_parallel_master:
15625  case OMPD_parallel_masked:
15626  case OMPD_parallel_sections:
15627  case OMPD_parallel_for:
15628  case OMPD_parallel_for_simd:
15629  case OMPD_parallel_loop:
15630  case OMPD_target:
15631  case OMPD_target_simd:
15632  case OMPD_target_parallel:
15633  case OMPD_target_parallel_for:
15634  case OMPD_target_parallel_for_simd:
15635  case OMPD_target_parallel_loop:
15636  case OMPD_threadprivate:
15637  case OMPD_allocate:
15638  case OMPD_taskyield:
15639  case OMPD_error:
15640  case OMPD_barrier:
15641  case OMPD_taskwait:
15642  case OMPD_cancellation_point:
15643  case OMPD_flush:
15644  case OMPD_depobj:
15645  case OMPD_scan:
15646  case OMPD_declare_reduction:
15647  case OMPD_declare_mapper:
15648  case OMPD_declare_simd:
15649  case OMPD_declare_variant:
15650  case OMPD_begin_declare_variant:
15651  case OMPD_end_declare_variant:
15652  case OMPD_declare_target:
15653  case OMPD_end_declare_target:
15654  case OMPD_loop:
15655  case OMPD_simd:
15656  case OMPD_tile:
15657  case OMPD_unroll:
15658  case OMPD_for:
15659  case OMPD_for_simd:
15660  case OMPD_sections:
15661  case OMPD_section:
15662  case OMPD_single:
15663  case OMPD_master:
15664  case OMPD_masked:
15665  case OMPD_critical:
15666  case OMPD_taskgroup:
15667  case OMPD_distribute:
15668  case OMPD_ordered:
15669  case OMPD_atomic:
15670  case OMPD_distribute_simd:
15671  case OMPD_requires:
15672  case OMPD_metadirective:
15673  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15674  case OMPD_unknown:
15675  default:
15676  llvm_unreachable("Unknown OpenMP directive");
15677  }
15678  break;
15679  case OMPC_thread_limit:
15680  switch (DKind) {
15681  case OMPD_target:
15682  case OMPD_target_teams:
15683  case OMPD_target_teams_distribute:
15684  case OMPD_target_teams_distribute_simd:
15685  case OMPD_target_teams_distribute_parallel_for:
15686  case OMPD_target_teams_distribute_parallel_for_simd:
15687  case OMPD_target_teams_loop:
15688  CaptureRegion = OMPD_target;
15689  break;
15690  case OMPD_teams_distribute_parallel_for:
15691  case OMPD_teams_distribute_parallel_for_simd:
15692  case OMPD_teams:
15693  case OMPD_teams_distribute:
15694  case OMPD_teams_distribute_simd:
15695  case OMPD_teams_loop:
15696  // Do not capture thread_limit-clause expressions.
15697  break;
15698  case OMPD_distribute_parallel_for:
15699  case OMPD_distribute_parallel_for_simd:
15700  case OMPD_task:
15701  case OMPD_taskloop:
15702  case OMPD_taskloop_simd:
15703  case OMPD_master_taskloop:
15704  case OMPD_masked_taskloop:
15705  case OMPD_master_taskloop_simd:
15706  case OMPD_masked_taskloop_simd:
15707  case OMPD_parallel_master_taskloop:
15708  case OMPD_parallel_masked_taskloop:
15709  case OMPD_parallel_master_taskloop_simd:
15710  case OMPD_parallel_masked_taskloop_simd:
15711  case OMPD_target_data:
15712  case OMPD_target_enter_data:
15713  case OMPD_target_exit_data:
15714  case OMPD_target_update:
15715  case OMPD_cancel:
15716  case OMPD_parallel:
15717  case OMPD_parallel_master:
15718  case OMPD_parallel_masked:
15719  case OMPD_parallel_sections:
15720  case OMPD_parallel_for:
15721  case OMPD_parallel_for_simd:
15722  case OMPD_parallel_loop:
15723  case OMPD_target_simd:
15724  case OMPD_target_parallel:
15725  case OMPD_target_parallel_for:
15726  case OMPD_target_parallel_for_simd:
15727  case OMPD_target_parallel_loop:
15728  case OMPD_threadprivate:
15729  case OMPD_allocate:
15730  case OMPD_taskyield:
15731  case OMPD_error:
15732  case OMPD_barrier:
15733  case OMPD_taskwait:
15734  case OMPD_cancellation_point:
15735  case OMPD_flush:
15736  case OMPD_depobj:
15737  case OMPD_scan:
15738  case OMPD_declare_reduction:
15739  case OMPD_declare_mapper:
15740  case OMPD_declare_simd:
15741  case OMPD_declare_variant:
15742  case OMPD_begin_declare_variant:
15743  case OMPD_end_declare_variant:
15744  case OMPD_declare_target:
15745  case OMPD_end_declare_target:
15746  case OMPD_loop:
15747  case OMPD_simd:
15748  case OMPD_tile:
15749  case OMPD_unroll:
15750  case OMPD_for:
15751  case OMPD_for_simd:
15752  case OMPD_sections:
15753  case OMPD_section:
15754  case OMPD_single:
15755  case OMPD_master:
15756  case OMPD_masked:
15757  case OMPD_critical:
15758  case OMPD_taskgroup:
15759  case OMPD_distribute:
15760  case OMPD_ordered:
15761  case OMPD_atomic:
15762  case OMPD_distribute_simd:
15763  case OMPD_requires:
15764  case OMPD_metadirective:
15765  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
15766  case OMPD_unknown:
15767  default:
15768  llvm_unreachable("Unknown OpenMP directive");
15769  }
15770  break;
15771  case OMPC_schedule:
15772  switch (DKind) {
15773  case OMPD_parallel_for:
15774  case OMPD_parallel_for_simd:
15775  case OMPD_distribute_parallel_for:
15776  case OMPD_distribute_parallel_for_simd:
15777  case OMPD_teams_distribute_parallel_for:
15778  case OMPD_teams_distribute_parallel_for_simd:
15779  case OMPD_target_parallel_for:
15780  case OMPD_target_parallel_for_simd:
15781  case OMPD_target_teams_distribute_parallel_for:
15782  case OMPD_target_teams_distribute_parallel_for_simd:
15783  CaptureRegion = OMPD_parallel;
15784  break;
15785  case OMPD_for:
15786  case OMPD_for_simd:
15787  // Do not capture schedule-clause expressions.
15788  break;
15789  case OMPD_task:
15790  case OMPD_taskloop:
15791  case OMPD_taskloop_simd:
15792  case OMPD_master_taskloop:
15793  case OMPD_masked_taskloop:
15794  case OMPD_master_taskloop_simd:
15795  case OMPD_masked_taskloop_simd:
15796  case OMPD_parallel_master_taskloop:
15797  case OMPD_parallel_masked_taskloop:
15798  case OMPD_parallel_master_taskloop_simd:
15799  case OMPD_parallel_masked_taskloop_simd:
15800  case OMPD_target_data:
15801  case OMPD_target_enter_data:
15802  case OMPD_target_exit_data:
15803  case OMPD_target_update:
15804  case OMPD_teams:
15805  case OMPD_teams_distribute:
15806  case OMPD_teams_distribute_simd:
15807  case OMPD_target_teams_distribute:
15808  case OMPD_target_teams_distribute_simd:
15809  case OMPD_target:
15810  case OMPD_target_simd:
15811  case OMPD_target_parallel:
15812  case OMPD_cancel:
15813  case OMPD_parallel:
15814  case OMPD_parallel_master:
15815  case OMPD_parallel_masked:
15816  case OMPD_parallel_sections:
15817  case OMPD_threadprivate:
15818  case OMPD_allocate:
15819  case OMPD_taskyield:
15820  case OMPD_error:
15821  case OMPD_barrier:
15822  case OMPD_taskwait:
15823  case OMPD_cancellation_point:
15824  case OMPD_flush:
15825  case OMPD_depobj:
15826  case OMPD_scan:
15827  case OMPD_declare_reduction:
15828  case OMPD_declare_mapper:
15829  case OMPD_declare_simd:
15830  case OMPD_declare_variant:
15831  case OMPD_begin_declare_variant:
15832  case OMPD_end_declare_variant:
15833  case OMPD_declare_target:
15834  case OMPD_end_declare_target:
15835  case OMPD_loop:
15836  case OMPD_teams_loop:
15837  case OMPD_target_teams_loop:
15838  case OMPD_parallel_loop:
15839  case OMPD_target_parallel_loop:
15840  case OMPD_simd:
15841  case OMPD_tile:
15842  case OMPD_unroll:
15843  case OMPD_sections:
15844  case OMPD_section:
15845  case OMPD_single:
15846  case OMPD_master:
15847  case OMPD_masked:
15848  case OMPD_critical:
15849  case OMPD_taskgroup:
15850  case OMPD_distribute:
15851  case OMPD_ordered:
15852  case OMPD_atomic:
15853  case OMPD_distribute_simd:
15854  case OMPD_target_teams:
15855  case OMPD_requires:
15856  case OMPD_metadirective:
15857  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
15858  case OMPD_unknown:
15859  default:
15860  llvm_unreachable("Unknown OpenMP directive");
15861  }
15862  break;
15863  case OMPC_dist_schedule:
15864  switch (DKind) {
15865  case OMPD_teams_distribute_parallel_for:
15866  case OMPD_teams_distribute_parallel_for_simd:
15867  case OMPD_teams_distribute:
15868  case OMPD_teams_distribute_simd:
15869  case OMPD_target_teams_distribute_parallel_for:
15870  case OMPD_target_teams_distribute_parallel_for_simd:
15871  case OMPD_target_teams_distribute:
15872  case OMPD_target_teams_distribute_simd:
15873  CaptureRegion = OMPD_teams;
15874  break;
15875  case OMPD_distribute_parallel_for:
15876  case OMPD_distribute_parallel_for_simd:
15877  case OMPD_distribute:
15878  case OMPD_distribute_simd:
15879  // Do not capture dist_schedule-clause expressions.
15880  break;
15881  case OMPD_parallel_for:
15882  case OMPD_parallel_for_simd:
15883  case OMPD_target_parallel_for_simd:
15884  case OMPD_target_parallel_for:
15885  case OMPD_task:
15886  case OMPD_taskloop:
15887  case OMPD_taskloop_simd:
15888  case OMPD_master_taskloop:
15889  case OMPD_masked_taskloop:
15890  case OMPD_master_taskloop_simd:
15891  case OMPD_masked_taskloop_simd:
15892  case OMPD_parallel_master_taskloop:
15893  case OMPD_parallel_masked_taskloop:
15894  case OMPD_parallel_master_taskloop_simd:
15895  case OMPD_parallel_masked_taskloop_simd:
15896  case OMPD_target_data:
15897  case OMPD_target_enter_data:
15898  case OMPD_target_exit_data:
15899  case OMPD_target_update:
15900  case OMPD_teams:
15901  case OMPD_target:
15902  case OMPD_target_simd:
15903  case OMPD_target_parallel:
15904  case OMPD_cancel:
15905  case OMPD_parallel:
15906  case OMPD_parallel_master:
15907  case OMPD_parallel_masked:
15908  case OMPD_parallel_sections:
15909  case OMPD_threadprivate:
15910  case OMPD_allocate:
15911  case OMPD_taskyield:
15912  case OMPD_error:
15913  case OMPD_barrier:
15914  case OMPD_taskwait:
15915  case OMPD_cancellation_point:
15916  case OMPD_flush:
15917  case OMPD_depobj:
15918  case OMPD_scan:
15919  case OMPD_declare_reduction:
15920  case OMPD_declare_mapper:
15921  case OMPD_declare_simd:
15922  case OMPD_declare_variant:
15923  case OMPD_begin_declare_variant:
15924  case OMPD_end_declare_variant:
15925  case OMPD_declare_target:
15926  case OMPD_end_declare_target:
15927  case OMPD_loop:
15928  case OMPD_teams_loop:
15929  case OMPD_target_teams_loop:
15930  case OMPD_parallel_loop:
15931  case OMPD_target_parallel_loop:
15932  case OMPD_simd:
15933  case OMPD_tile:
15934  case OMPD_unroll:
15935  case OMPD_for:
15936  case OMPD_for_simd:
15937  case OMPD_sections:
15938  case OMPD_section:
15939  case OMPD_single:
15940  case OMPD_master:
15941  case OMPD_masked:
15942  case OMPD_critical:
15943  case OMPD_taskgroup:
15944  case OMPD_ordered:
15945  case OMPD_atomic:
15946  case OMPD_target_teams:
15947  case OMPD_requires:
15948  case OMPD_metadirective:
15949  llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
15950  case OMPD_unknown:
15951  default:
15952  llvm_unreachable("Unknown OpenMP directive");
15953  }
15954  break;
15955  case OMPC_ompx_dyn_cgroup_mem:
15956  switch (DKind) {
15957  case OMPD_target:
15958  case OMPD_target_simd:
15959  case OMPD_target_teams:
15960  case OMPD_target_parallel:
15961  case OMPD_target_teams_distribute:
15962  case OMPD_target_teams_distribute_simd:
15963  case OMPD_target_parallel_for:
15964  case OMPD_target_parallel_for_simd:
15965  case OMPD_target_parallel_loop:
15966  case OMPD_target_teams_distribute_parallel_for:
15967  case OMPD_target_teams_distribute_parallel_for_simd:
15968  case OMPD_target_teams_loop:
15969  CaptureRegion = OMPD_target;
15970  break;
15971  default:
15972  llvm_unreachable("Unknown OpenMP directive");
15973  }
15974  break;
15975  case OMPC_device:
15976  switch (DKind) {
15977  case OMPD_target_update:
15978  case OMPD_target_enter_data:
15979  case OMPD_target_exit_data:
15980  case OMPD_target:
15981  case OMPD_target_simd:
15982  case OMPD_target_teams:
15983  case OMPD_target_parallel:
15984  case OMPD_target_teams_distribute:
15985  case OMPD_target_teams_distribute_simd:
15986  case OMPD_target_parallel_for:
15987  case OMPD_target_parallel_for_simd:
15988  case OMPD_target_parallel_loop:
15989  case OMPD_target_teams_distribute_parallel_for:
15990  case OMPD_target_teams_distribute_parallel_for_simd:
15991  case OMPD_target_teams_loop:
15992  case OMPD_dispatch:
15993  CaptureRegion = OMPD_task;
15994  break;
15995  case OMPD_target_data:
15996  case OMPD_interop:
15997  // Do not capture device-clause expressions.
15998  break;
15999  case OMPD_teams_distribute_parallel_for:
16000  case OMPD_teams_distribute_parallel_for_simd:
16001  case OMPD_teams:
16002  case OMPD_teams_distribute:
16003  case OMPD_teams_distribute_simd:
16004  case OMPD_distribute_parallel_for:
16005  case OMPD_distribute_parallel_for_simd:
16006  case OMPD_task:
16007  case OMPD_taskloop:
16008  case OMPD_taskloop_simd:
16009  case OMPD_master_taskloop:
16010  case OMPD_masked_taskloop:
16011  case OMPD_master_taskloop_simd:
16012  case OMPD_masked_taskloop_simd:
16013  case OMPD_parallel_master_taskloop:
16014  case OMPD_parallel_masked_taskloop:
16015  case OMPD_parallel_master_taskloop_simd:
16016  case OMPD_parallel_masked_taskloop_simd:
16017  case OMPD_cancel:
16018  case OMPD_parallel:
16019  case OMPD_parallel_master:
16020  case OMPD_parallel_masked:
16021  case OMPD_parallel_sections:
16022  case OMPD_parallel_for:
16023  case OMPD_parallel_for_simd:
16024  case OMPD_threadprivate:
16025  case OMPD_allocate:
16026  case OMPD_taskyield:
16027  case OMPD_error:
16028  case OMPD_barrier:
16029  case OMPD_taskwait:
16030  case OMPD_cancellation_point:
16031  case OMPD_flush:
16032  case OMPD_depobj:
16033  case OMPD_scan:
16034  case OMPD_declare_reduction:
16035  case OMPD_declare_mapper:
16036  case OMPD_declare_simd:
16037  case OMPD_declare_variant:
16038  case OMPD_begin_declare_variant:
16039  case OMPD_end_declare_variant:
16040  case OMPD_declare_target:
16041  case OMPD_end_declare_target:
16042  case OMPD_loop:
16043  case OMPD_teams_loop:
16044  case OMPD_parallel_loop:
16045  case OMPD_simd:
16046  case OMPD_tile:
16047  case OMPD_unroll:
16048  case OMPD_for:
16049  case OMPD_for_simd:
16050  case OMPD_sections:
16051  case OMPD_section:
16052  case OMPD_single:
16053  case OMPD_master:
16054  case OMPD_masked:
16055  case OMPD_critical:
16056  case OMPD_taskgroup:
16057  case OMPD_distribute:
16058  case OMPD_ordered:
16059  case OMPD_atomic:
16060  case OMPD_distribute_simd:
16061  case OMPD_requires:
16062  case OMPD_metadirective:
16063  llvm_unreachable("Unexpected OpenMP directive with device-clause");
16064  case OMPD_unknown:
16065  default:
16066  llvm_unreachable("Unknown OpenMP directive");
16067  }
16068  break;
16069  case OMPC_grainsize:
16070  case OMPC_num_tasks:
16071  case OMPC_final:
16072  case OMPC_priority:
16073  switch (DKind) {
16074  case OMPD_task:
16075  case OMPD_taskloop:
16076  case OMPD_taskloop_simd:
16077  case OMPD_master_taskloop:
16078  case OMPD_masked_taskloop:
16079  case OMPD_master_taskloop_simd:
16080  case OMPD_masked_taskloop_simd:
16081  break;
16082  case OMPD_parallel_masked_taskloop:
16083  case OMPD_parallel_masked_taskloop_simd:
16084  case OMPD_parallel_master_taskloop:
16085  case OMPD_parallel_master_taskloop_simd:
16086  CaptureRegion = OMPD_parallel;
16087  break;
16088  case OMPD_target_update:
16089  case OMPD_target_enter_data:
16090  case OMPD_target_exit_data:
16091  case OMPD_target:
16092  case OMPD_target_simd:
16093  case OMPD_target_teams:
16094  case OMPD_target_parallel:
16095  case OMPD_target_teams_distribute:
16096  case OMPD_target_teams_distribute_simd:
16097  case OMPD_target_parallel_for:
16098  case OMPD_target_parallel_for_simd:
16099  case OMPD_target_teams_distribute_parallel_for:
16100  case OMPD_target_teams_distribute_parallel_for_simd:
16101  case OMPD_target_data:
16102  case OMPD_teams_distribute_parallel_for:
16103  case OMPD_teams_distribute_parallel_for_simd:
16104  case OMPD_teams:
16105  case OMPD_teams_distribute:
16106  case OMPD_teams_distribute_simd:
16107  case OMPD_distribute_parallel_for:
16108  case OMPD_distribute_parallel_for_simd:
16109  case OMPD_cancel:
16110  case OMPD_parallel:
16111  case OMPD_parallel_master:
16112  case OMPD_parallel_masked:
16113  case OMPD_parallel_sections:
16114  case OMPD_parallel_for:
16115  case OMPD_parallel_for_simd:
16116  case OMPD_threadprivate:
16117  case OMPD_allocate:
16118  case OMPD_taskyield:
16119  case OMPD_error:
16120  case OMPD_barrier:
16121  case OMPD_taskwait:
16122  case OMPD_cancellation_point:
16123  case OMPD_flush:
16124  case OMPD_depobj:
16125  case OMPD_scan:
16126  case OMPD_declare_reduction:
16127  case OMPD_declare_mapper:
16128  case OMPD_declare_simd:
16129  case OMPD_declare_variant:
16130  case OMPD_begin_declare_variant:
16131  case OMPD_end_declare_variant:
16132  case OMPD_declare_target:
16133  case OMPD_end_declare_target:
16134  case OMPD_loop:
16135  case OMPD_teams_loop:
16136  case OMPD_target_teams_loop:
16137  case OMPD_parallel_loop:
16138  case OMPD_target_parallel_loop:
16139  case OMPD_simd:
16140  case OMPD_tile:
16141  case OMPD_unroll:
16142  case OMPD_for:
16143  case OMPD_for_simd:
16144  case OMPD_sections:
16145  case OMPD_section:
16146  case OMPD_single:
16147  case OMPD_master:
16148  case OMPD_masked:
16149  case OMPD_critical:
16150  case OMPD_taskgroup:
16151  case OMPD_distribute:
16152  case OMPD_ordered:
16153  case OMPD_atomic:
16154  case OMPD_distribute_simd:
16155  case OMPD_requires:
16156  case OMPD_metadirective:
16157  llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16158  case OMPD_unknown:
16159  default:
16160  llvm_unreachable("Unknown OpenMP directive");
16161  }
16162  break;
16163  case OMPC_novariants:
16164  case OMPC_nocontext:
16165  switch (DKind) {
16166  case OMPD_dispatch:
16167  CaptureRegion = OMPD_task;
16168  break;
16169  default:
16170  llvm_unreachable("Unexpected OpenMP directive");
16171  }
16172  break;
16173  case OMPC_filter:
16174  // Do not capture filter-clause expressions.
16175  break;
16176  case OMPC_when:
16177  if (DKind == OMPD_metadirective) {
16178  CaptureRegion = OMPD_metadirective;
16179  } else if (DKind == OMPD_unknown) {
16180  llvm_unreachable("Unknown OpenMP directive");
16181  } else {
16182  llvm_unreachable("Unexpected OpenMP directive with when clause");
16183  }
16184  break;
16185  case OMPC_firstprivate:
16186  case OMPC_lastprivate:
16187  case OMPC_reduction:
16188  case OMPC_task_reduction:
16189  case OMPC_in_reduction:
16190  case OMPC_linear:
16191  case OMPC_default:
16192  case OMPC_proc_bind:
16193  case OMPC_safelen:
16194  case OMPC_simdlen:
16195  case OMPC_sizes:
16196  case OMPC_allocator:
16197  case OMPC_collapse:
16198  case OMPC_private:
16199  case OMPC_shared:
16200  case OMPC_aligned:
16201  case OMPC_copyin:
16202  case OMPC_copyprivate:
16203  case OMPC_ordered:
16204  case OMPC_nowait:
16205  case OMPC_untied:
16206  case OMPC_mergeable:
16207  case OMPC_threadprivate:
16208  case OMPC_allocate:
16209  case OMPC_flush:
16210  case OMPC_depobj:
16211  case OMPC_read:
16212  case OMPC_write:
16213  case OMPC_update:
16214  case OMPC_capture:
16215  case OMPC_compare:
16216  case OMPC_seq_cst:
16217  case OMPC_acq_rel:
16218  case OMPC_acquire:
16219  case OMPC_release:
16220  case OMPC_relaxed:
16221  case OMPC_depend:
16222  case OMPC_threads:
16223  case OMPC_simd:
16224  case OMPC_map:
16225  case OMPC_nogroup:
16226  case OMPC_hint:
16227  case OMPC_defaultmap:
16228  case OMPC_unknown:
16229  case OMPC_uniform:
16230  case OMPC_to:
16231  case OMPC_from:
16232  case OMPC_use_device_ptr:
16233  case OMPC_use_device_addr:
16234  case OMPC_is_device_ptr:
16235  case OMPC_unified_address:
16236  case OMPC_unified_shared_memory:
16237  case OMPC_reverse_offload:
16238  case OMPC_dynamic_allocators:
16239  case OMPC_atomic_default_mem_order:
16240  case OMPC_device_type:
16241  case OMPC_match:
16242  case OMPC_nontemporal:
16243  case OMPC_order:
16244  case OMPC_at:
16245  case OMPC_severity:
16246  case OMPC_message:
16247  case OMPC_destroy:
16248  case OMPC_detach:
16249  case OMPC_inclusive:
16250  case OMPC_exclusive:
16251  case OMPC_uses_allocators:
16252  case OMPC_affinity:
16253  case OMPC_bind:
16254  default:
16255  llvm_unreachable("Unexpected OpenMP clause.");
16256  }
16257  return CaptureRegion;
16258 }
16259 
16261  Expr *Condition, SourceLocation StartLoc,
16262  SourceLocation LParenLoc,
16263  SourceLocation NameModifierLoc,
16264  SourceLocation ColonLoc,
16265  SourceLocation EndLoc) {
16266  Expr *ValExpr = Condition;
16267  Stmt *HelperValStmt = nullptr;
16268  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16269  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16270  !Condition->isInstantiationDependent() &&
16271  !Condition->containsUnexpandedParameterPack()) {
16272  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16273  if (Val.isInvalid())
16274  return nullptr;
16275 
16276  ValExpr = Val.get();
16277 
16278  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16279  CaptureRegion = getOpenMPCaptureRegionForClause(
16280  DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16281  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16282  ValExpr = MakeFullExpr(ValExpr).get();
16283  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16284  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16285  HelperValStmt = buildPreInits(Context, Captures);
16286  }
16287  }
16288 
16289  return new (Context)
16290  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16291  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16292 }
16293 
16295  SourceLocation StartLoc,
16296  SourceLocation LParenLoc,
16297  SourceLocation EndLoc) {
16298  Expr *ValExpr = Condition;
16299  Stmt *HelperValStmt = nullptr;
16300  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16301  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16302  !Condition->isInstantiationDependent() &&
16303  !Condition->containsUnexpandedParameterPack()) {
16304  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16305  if (Val.isInvalid())
16306  return nullptr;
16307 
16308  ValExpr = MakeFullExpr(Val.get()).get();
16309 
16310  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16311  CaptureRegion =
16312  getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16313  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16314  ValExpr = MakeFullExpr(ValExpr).get();
16315  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16316  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16317  HelperValStmt = buildPreInits(Context, Captures);
16318  }
16319  }
16320 
16321  return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16322  StartLoc, LParenLoc, EndLoc);
16323 }
16324 
16326  Expr *Op) {
16327  if (!Op)
16328  return ExprError();
16329 
16330  class IntConvertDiagnoser : public ICEConvertDiagnoser {
16331  public:
16332  IntConvertDiagnoser()
16333  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16334  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16335  QualType T) override {
16336  return S.Diag(Loc, diag::err_omp_not_integral) << T;
16337  }
16338  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16339  QualType T) override {
16340  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16341  }
16342  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16343  QualType T,
16344  QualType ConvTy) override {
16345  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16346  }
16347  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16348  QualType ConvTy) override {
16349  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16350  << ConvTy->isEnumeralType() << ConvTy;
16351  }
16352  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16353  QualType T) override {
16354  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16355  }
16356  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16357  QualType ConvTy) override {
16358  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16359  << ConvTy->isEnumeralType() << ConvTy;
16360  }
16361  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16362  QualType) override {
16363  llvm_unreachable("conversion functions are permitted");
16364  }
16365  } ConvertDiagnoser;
16366  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16367 }
16368 
16369 static bool
16371  bool StrictlyPositive, bool BuildCapture = false,
16372  OpenMPDirectiveKind DKind = OMPD_unknown,
16373  OpenMPDirectiveKind *CaptureRegion = nullptr,
16374  Stmt **HelperValStmt = nullptr) {
16375  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16376  !ValExpr->isInstantiationDependent()) {
16377  SourceLocation Loc = ValExpr->getExprLoc();
16378  ExprResult Value =
16379  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16380  if (Value.isInvalid())
16381  return false;
16382 
16383  ValExpr = Value.get();
16384  // The expression must evaluate to a non-negative integer value.
16385  if (std::optional<llvm::APSInt> Result =
16386  ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16387  if (Result->isSigned() &&
16388  !((!StrictlyPositive && Result->isNonNegative()) ||
16389  (StrictlyPositive && Result->isStrictlyPositive()))) {
16390  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16391  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16392  << ValExpr->getSourceRange();
16393  return false;
16394  }
16395  }
16396  if (!BuildCapture)
16397  return true;
16398  *CaptureRegion =
16399  getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16400  if (*CaptureRegion != OMPD_unknown &&
16401  !SemaRef.CurContext->isDependentContext()) {
16402  ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16403  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16404  ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16405  *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16406  }
16407  }
16408  return true;
16409 }
16410 
16412  SourceLocation StartLoc,
16413  SourceLocation LParenLoc,
16414  SourceLocation EndLoc) {
16415  Expr *ValExpr = NumThreads;
16416  Stmt *HelperValStmt = nullptr;
16417 
16418  // OpenMP [2.5, Restrictions]
16419  // The num_threads expression must evaluate to a positive integer value.
16420  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16421  /*StrictlyPositive=*/true))
16422  return nullptr;
16423 
16424  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16425  OpenMPDirectiveKind CaptureRegion =
16426  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16427  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16428  ValExpr = MakeFullExpr(ValExpr).get();
16429  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16430  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16431  HelperValStmt = buildPreInits(Context, Captures);
16432  }
16433 
16434  return new (Context) OMPNumThreadsClause(
16435  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16436 }
16437 
16438 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16439  OpenMPClauseKind CKind,
16440  bool StrictlyPositive,
16441  bool SuppressExprDiags) {
16442  if (!E)
16443  return ExprError();
16444  if (E->isValueDependent() || E->isTypeDependent() ||
16446  return E;
16447 
16448  llvm::APSInt Result;
16449  ExprResult ICE;
16450  if (SuppressExprDiags) {
16451  // Use a custom diagnoser that suppresses 'note' diagnostics about the
16452  // expression.
16453  struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16454  SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16455  Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16456  SourceLocation Loc) override {
16457  llvm_unreachable("Diagnostic suppressed");
16458  }
16459  } Diagnoser;
16460  ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16461  } else {
16462  ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16463  }
16464  if (ICE.isInvalid())
16465  return ExprError();
16466 
16467  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16468  (!StrictlyPositive && !Result.isNonNegative())) {
16469  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16470  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16471  << E->getSourceRange();
16472  return ExprError();
16473  }
16474  if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16475  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16476  << E->getSourceRange();
16477  return ExprError();
16478  }
16479  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16480  DSAStack->setAssociatedLoops(Result.getExtValue());
16481  else if (CKind == OMPC_ordered)
16482  DSAStack->setAssociatedLoops(Result.getExtValue());
16483  return ICE;
16484 }
16485 
16487  SourceLocation LParenLoc,
16488  SourceLocation EndLoc) {
16489  // OpenMP [2.8.1, simd construct, Description]
16490  // The parameter of the safelen clause must be a constant
16491  // positive integer expression.
16492  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16493  if (Safelen.isInvalid())
16494  return nullptr;
16495  return new (Context)
16496  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16497 }
16498 
16500  SourceLocation LParenLoc,
16501  SourceLocation EndLoc) {
16502  // OpenMP [2.8.1, simd construct, Description]
16503  // The parameter of the simdlen clause must be a constant
16504  // positive integer expression.
16505  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16506  if (Simdlen.isInvalid())
16507  return nullptr;
16508  return new (Context)
16509  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16510 }
16511 
16512 /// Tries to find omp_allocator_handle_t type.
16514  DSAStackTy *Stack) {
16515  if (!Stack->getOMPAllocatorHandleT().isNull())
16516  return true;
16517 
16518  // Set the allocator handle type.
16519  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16520  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16521  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16522  S.Diag(Loc, diag::err_omp_implied_type_not_found)
16523  << "omp_allocator_handle_t";
16524  return false;
16525  }
16526  QualType AllocatorHandleEnumTy = PT.get();
16527  AllocatorHandleEnumTy.addConst();
16528  Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16529 
16530  // Fill the predefined allocator map.
16531  bool ErrorFound = false;
16532  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16533  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16534  StringRef Allocator =
16535  OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16536  DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16537  auto *VD = dyn_cast_or_null<ValueDecl>(
16538  S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16539  if (!VD) {
16540  ErrorFound = true;
16541  break;
16542  }
16543  QualType AllocatorType =
16545  ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16546  if (!Res.isUsable()) {
16547  ErrorFound = true;
16548  break;
16549  }
16550  Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16552  /* AllowExplicit */ true);
16553  if (!Res.isUsable()) {
16554  ErrorFound = true;
16555  break;
16556  }
16557  Stack->setAllocator(AllocatorKind, Res.get());
16558  }
16559  if (ErrorFound) {
16560  S.Diag(Loc, diag::err_omp_implied_type_not_found)
16561  << "omp_allocator_handle_t";
16562  return false;
16563  }
16564 
16565  return true;
16566 }
16567 
16569  SourceLocation LParenLoc,
16570  SourceLocation EndLoc) {
16571  // OpenMP [2.11.3, allocate Directive, Description]
16572  // allocator is an expression of omp_allocator_handle_t type.
16573  if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16574  return nullptr;
16575 
16576  ExprResult Allocator = DefaultLvalueConversion(A);
16577  if (Allocator.isInvalid())
16578  return nullptr;
16579  Allocator = PerformImplicitConversion(Allocator.get(),
16580  DSAStack->getOMPAllocatorHandleT(),
16582  /*AllowExplicit=*/true);
16583  if (Allocator.isInvalid())
16584  return nullptr;
16585  return new (Context)
16586  OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16587 }
16588 
16590  SourceLocation StartLoc,
16591  SourceLocation LParenLoc,
16592  SourceLocation EndLoc) {
16593  // OpenMP [2.7.1, loop construct, Description]
16594  // OpenMP [2.8.1, simd construct, Description]
16595  // OpenMP [2.9.6, distribute construct, Description]
16596  // The parameter of the collapse clause must be a constant
16597  // positive integer expression.
16598  ExprResult NumForLoopsResult =
16599  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16600  if (NumForLoopsResult.isInvalid())
16601  return nullptr;
16602  return new (Context)
16603  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16604 }
16605 
16607  SourceLocation EndLoc,
16608  SourceLocation LParenLoc,
16609  Expr *NumForLoops) {
16610  // OpenMP [2.7.1, loop construct, Description]
16611  // OpenMP [2.8.1, simd construct, Description]
16612  // OpenMP [2.9.6, distribute construct, Description]
16613  // The parameter of the ordered clause must be a constant
16614  // positive integer expression if any.
16615  if (NumForLoops && LParenLoc.isValid()) {
16616  ExprResult NumForLoopsResult =
16617  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16618  if (NumForLoopsResult.isInvalid())
16619  return nullptr;
16620  NumForLoops = NumForLoopsResult.get();
16621  } else {
16622  NumForLoops = nullptr;
16623  }
16624  auto *Clause = OMPOrderedClause::Create(
16625  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16626  StartLoc, LParenLoc, EndLoc);
16627  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16628  return Clause;
16629 }
16630 
16632  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16633  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16634  OMPClause *Res = nullptr;
16635  switch (Kind) {
16636  case OMPC_default:
16637  Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16638  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16639  break;
16640  case OMPC_proc_bind:
16641  Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16642  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16643  break;
16644  case OMPC_atomic_default_mem_order:
16646  static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16647  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16648  break;
16649  case OMPC_update:
16650  Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16651  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16652  break;
16653  case OMPC_bind:
16654  Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16655  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16656  break;
16657  case OMPC_at:
16658  Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16659  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16660  break;
16661  case OMPC_severity:
16663  static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16664  LParenLoc, EndLoc);
16665  break;
16666  case OMPC_if:
16667  case OMPC_final:
16668  case OMPC_num_threads:
16669  case OMPC_safelen:
16670  case OMPC_simdlen:
16671  case OMPC_sizes:
16672  case OMPC_allocator:
16673  case OMPC_collapse:
16674  case OMPC_schedule:
16675  case OMPC_private:
16676  case OMPC_firstprivate:
16677  case OMPC_lastprivate:
16678  case OMPC_shared:
16679  case OMPC_reduction:
16680  case OMPC_task_reduction:
16681  case OMPC_in_reduction:
16682  case OMPC_linear:
16683  case OMPC_aligned:
16684  case OMPC_copyin:
16685  case OMPC_copyprivate:
16686  case OMPC_ordered:
16687  case OMPC_nowait:
16688  case OMPC_untied:
16689  case OMPC_mergeable:
16690  case OMPC_threadprivate:
16691  case OMPC_allocate:
16692  case OMPC_flush:
16693  case OMPC_depobj:
16694  case OMPC_read:
16695  case OMPC_write:
16696  case OMPC_capture:
16697  case OMPC_compare:
16698  case OMPC_seq_cst:
16699  case OMPC_acq_rel:
16700  case OMPC_acquire:
16701  case OMPC_release:
16702  case OMPC_relaxed:
16703  case OMPC_depend:
16704  case OMPC_device:
16705  case OMPC_threads:
16706  case OMPC_simd:
16707  case OMPC_map:
16708  case OMPC_num_teams:
16709  case OMPC_thread_limit:
16710  case OMPC_priority:
16711  case OMPC_grainsize:
16712  case OMPC_nogroup:
16713  case OMPC_num_tasks:
16714  case OMPC_hint:
16715  case OMPC_dist_schedule:
16716  case OMPC_defaultmap:
16717  case OMPC_unknown:
16718  case OMPC_uniform:
16719  case OMPC_to:
16720  case OMPC_from:
16721  case OMPC_use_device_ptr:
16722  case OMPC_use_device_addr:
16723  case OMPC_is_device_ptr:
16724  case OMPC_has_device_addr:
16725  case OMPC_unified_address:
16726  case OMPC_unified_shared_memory:
16727  case OMPC_reverse_offload:
16728  case OMPC_dynamic_allocators:
16729  case OMPC_device_type:
16730  case OMPC_match:
16731  case OMPC_nontemporal:
16732  case OMPC_destroy:
16733  case OMPC_novariants:
16734  case OMPC_nocontext:
16735  case OMPC_detach:
16736  case OMPC_inclusive:
16737  case OMPC_exclusive:
16738  case OMPC_uses_allocators:
16739  case OMPC_affinity:
16740  case OMPC_when:
16741  case OMPC_message:
16742  default:
16743  llvm_unreachable("Clause is not allowed.");
16744  }
16745  return Res;
16746 }
16747 
16748 static std::string
16749 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
16750  ArrayRef<unsigned> Exclude = std::nullopt) {
16751  SmallString<256> Buffer;
16752  llvm::raw_svector_ostream Out(Buffer);
16753  unsigned Skipped = Exclude.size();
16754  for (unsigned I = First; I < Last; ++I) {
16755  if (llvm::is_contained(Exclude, I)) {
16756  --Skipped;
16757  continue;
16758  }
16759  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
16760  if (I + Skipped + 2 == Last)
16761  Out << " or ";
16762  else if (I + Skipped + 1 != Last)
16763  Out << ", ";
16764  }
16765  return std::string(Out.str());
16766 }
16767 
16769  SourceLocation KindKwLoc,
16770  SourceLocation StartLoc,
16771  SourceLocation LParenLoc,
16772  SourceLocation EndLoc) {
16773  if (Kind == OMP_DEFAULT_unknown) {
16774  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16775  << getListOfPossibleValues(OMPC_default, /*First=*/0,
16776  /*Last=*/unsigned(OMP_DEFAULT_unknown))
16777  << getOpenMPClauseName(OMPC_default);
16778  return nullptr;
16779  }
16780 
16781  switch (Kind) {
16782  case OMP_DEFAULT_none:
16783  DSAStack->setDefaultDSANone(KindKwLoc);
16784  break;
16785  case OMP_DEFAULT_shared:
16786  DSAStack->setDefaultDSAShared(KindKwLoc);
16787  break;
16788  case OMP_DEFAULT_firstprivate:
16789  DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
16790  break;
16791  case OMP_DEFAULT_private:
16792  DSAStack->setDefaultDSAPrivate(KindKwLoc);
16793  break;
16794  default:
16795  llvm_unreachable("DSA unexpected in OpenMP default clause");
16796  }
16797 
16798  return new (Context)
16799  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16800 }
16801 
16803  SourceLocation KindKwLoc,
16804  SourceLocation StartLoc,
16805  SourceLocation LParenLoc,
16806  SourceLocation EndLoc) {
16807  if (Kind == OMP_PROC_BIND_unknown) {
16808  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16809  << getListOfPossibleValues(OMPC_proc_bind,
16810  /*First=*/unsigned(OMP_PROC_BIND_master),
16811  /*Last=*/
16812  unsigned(LangOpts.OpenMP > 50
16813  ? OMP_PROC_BIND_primary
16814  : OMP_PROC_BIND_spread) +
16815  1)
16816  << getOpenMPClauseName(OMPC_proc_bind);
16817  return nullptr;
16818  }
16819  if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16820  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16821  << getListOfPossibleValues(OMPC_proc_bind,
16822  /*First=*/unsigned(OMP_PROC_BIND_master),
16823  /*Last=*/
16824  unsigned(OMP_PROC_BIND_spread) + 1)
16825  << getOpenMPClauseName(OMPC_proc_bind);
16826  return new (Context)
16827  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16828 }
16829 
16832  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16834  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16836  OMPC_atomic_default_mem_order, /*First=*/0,
16838  << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16839  return nullptr;
16840  }
16841  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16842  LParenLoc, EndLoc);
16843 }
16844 
16846  SourceLocation KindKwLoc,
16847  SourceLocation StartLoc,
16848  SourceLocation LParenLoc,
16849  SourceLocation EndLoc) {
16850  if (Kind == OMPC_AT_unknown) {
16851  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16852  << getListOfPossibleValues(OMPC_at, /*First=*/0,
16853  /*Last=*/OMPC_AT_unknown)
16854  << getOpenMPClauseName(OMPC_at);
16855  return nullptr;
16856  }
16857  return new (Context)
16858  OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16859 }
16860 
16862  SourceLocation KindKwLoc,
16863  SourceLocation StartLoc,
16864  SourceLocation LParenLoc,
16865  SourceLocation EndLoc) {
16866  if (Kind == OMPC_SEVERITY_unknown) {
16867  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16868  << getListOfPossibleValues(OMPC_severity, /*First=*/0,
16869  /*Last=*/OMPC_SEVERITY_unknown)
16870  << getOpenMPClauseName(OMPC_severity);
16871  return nullptr;
16872  }
16873  return new (Context)
16874  OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16875 }
16876 
16878  SourceLocation LParenLoc,
16879  SourceLocation EndLoc) {
16880  assert(ME && "NULL expr in Message clause");
16881  if (!isa<StringLiteral>(ME)) {
16882  Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
16883  << getOpenMPClauseName(OMPC_message);
16884  return nullptr;
16885  }
16886  return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
16887 }
16888 
16891  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16892  SourceLocation KindLoc, SourceLocation EndLoc) {
16893  if (Kind != OMPC_ORDER_concurrent ||
16894  (LangOpts.OpenMP < 51 && MLoc.isValid())) {
16895  // Kind should be concurrent,
16896  // Modifiers introduced in OpenMP 5.1
16897  static_assert(OMPC_ORDER_unknown > 0,
16898  "OMPC_ORDER_unknown not greater than 0");
16899 
16900  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16901  << getListOfPossibleValues(OMPC_order,
16902  /*First=*/0,
16903  /*Last=*/OMPC_ORDER_unknown)
16904  << getOpenMPClauseName(OMPC_order);
16905  return nullptr;
16906  }
16907  if (LangOpts.OpenMP >= 51) {
16908  if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
16909  Diag(MLoc, diag::err_omp_unexpected_clause_value)
16910  << getListOfPossibleValues(OMPC_order,
16911  /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
16912  /*Last=*/OMPC_ORDER_MODIFIER_last)
16913  << getOpenMPClauseName(OMPC_order);
16914  } else {
16915  DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
16916  if (DSAStack->getCurScope()) {
16917  // mark the current scope with 'order' flag
16918  unsigned existingFlags = DSAStack->getCurScope()->getFlags();
16919  DSAStack->getCurScope()->setFlags(existingFlags |
16921  }
16922  }
16923  }
16924  return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
16925  EndLoc, Modifier, MLoc);
16926 }
16927 
16929  SourceLocation KindKwLoc,
16930  SourceLocation StartLoc,
16931  SourceLocation LParenLoc,
16932  SourceLocation EndLoc) {
16933  if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16934  Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16935  SmallVector<unsigned> Except = {
16936  OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16937  OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16938  if (LangOpts.OpenMP < 51)
16939  Except.push_back(OMPC_DEPEND_inoutset);
16940  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16941  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16942  /*Last=*/OMPC_DEPEND_unknown, Except)
16943  << getOpenMPClauseName(OMPC_update);
16944  return nullptr;
16945  }
16946  return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
16947  EndLoc);
16948 }
16949 
16951  SourceLocation StartLoc,
16952  SourceLocation LParenLoc,
16953  SourceLocation EndLoc) {
16954  for (Expr *SizeExpr : SizeExprs) {
16955  ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16956  SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
16957  if (!NumForLoopsResult.isUsable())
16958  return nullptr;
16959  }
16960 
16961  DSAStack->setAssociatedLoops(SizeExprs.size());
16962  return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16963  SizeExprs);
16964 }
16965 
16967  SourceLocation EndLoc) {
16968  return OMPFullClause::Create(Context, StartLoc, EndLoc);
16969 }
16970 
16972  SourceLocation StartLoc,
16973  SourceLocation LParenLoc,
16974  SourceLocation EndLoc) {
16975  if (FactorExpr) {
16976  // If an argument is specified, it must be a constant (or an unevaluated
16977  // template expression).
16978  ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16979  FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16980  if (FactorResult.isInvalid())
16981  return nullptr;
16982  FactorExpr = FactorResult.get();
16983  }
16984 
16985  return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16986  FactorExpr);
16987 }
16988 
16990  SourceLocation LParenLoc,
16991  SourceLocation EndLoc) {
16992  ExprResult AlignVal;
16993  AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16994  if (AlignVal.isInvalid())
16995  return nullptr;
16996  return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
16997  EndLoc);
16998 }
16999 
17002  SourceLocation StartLoc, SourceLocation LParenLoc,
17003  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17004  SourceLocation EndLoc) {
17005  OMPClause *Res = nullptr;
17006  switch (Kind) {
17007  case OMPC_schedule:
17008  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17009  assert(Argument.size() == NumberOfElements &&
17010  ArgumentLoc.size() == NumberOfElements);
17012  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17013  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17014  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17015  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17016  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17017  break;
17018  case OMPC_if:
17019  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17020  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17021  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17022  DelimLoc, EndLoc);
17023  break;
17024  case OMPC_dist_schedule:
17026  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17027  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17028  break;
17029  case OMPC_defaultmap:
17030  enum { Modifier, DefaultmapKind };
17032  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17033  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17034  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17035  EndLoc);
17036  break;
17037  case OMPC_order:
17038  enum { OrderModifier, OrderKind };
17039  Res = ActOnOpenMPOrderClause(
17040  static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17041  static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17042  LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17043  break;
17044  case OMPC_device:
17045  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17047  static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17048  StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17049  break;
17050  case OMPC_grainsize:
17051  assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17052  "Modifier for grainsize clause and its location are expected.");
17054  static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17055  StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17056  break;
17057  case OMPC_num_tasks:
17058  assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17059  "Modifier for num_tasks clause and its location are expected.");
17061  static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17062  StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17063  break;
17064  case OMPC_final:
17065  case OMPC_num_threads:
17066  case OMPC_safelen:
17067  case OMPC_simdlen:
17068  case OMPC_sizes:
17069  case OMPC_allocator:
17070  case OMPC_collapse:
17071  case OMPC_default:
17072  case OMPC_proc_bind:
17073  case OMPC_private:
17074  case OMPC_firstprivate:
17075  case OMPC_lastprivate:
17076  case OMPC_shared:
17077  case OMPC_reduction:
17078  case OMPC_task_reduction:
17079  case OMPC_in_reduction:
17080  case OMPC_linear:
17081  case OMPC_aligned:
17082  case OMPC_copyin:
17083  case OMPC_copyprivate:
17084  case OMPC_ordered:
17085  case OMPC_nowait:
17086  case OMPC_untied:
17087  case OMPC_mergeable:
17088  case OMPC_threadprivate:
17089  case OMPC_allocate:
17090  case OMPC_flush:
17091  case OMPC_depobj:
17092  case OMPC_read:
17093  case OMPC_write:
17094  case OMPC_update:
17095  case OMPC_capture:
17096  case OMPC_compare:
17097  case OMPC_seq_cst:
17098  case OMPC_acq_rel:
17099  case OMPC_acquire:
17100  case OMPC_release:
17101  case OMPC_relaxed:
17102  case OMPC_depend:
17103  case OMPC_threads:
17104  case OMPC_simd:
17105  case OMPC_map:
17106  case OMPC_num_teams:
17107  case OMPC_thread_limit:
17108  case OMPC_priority:
17109  case OMPC_nogroup:
17110  case OMPC_hint:
17111  case OMPC_unknown:
17112  case OMPC_uniform:
17113  case OMPC_to:
17114  case OMPC_from:
17115  case OMPC_use_device_ptr:
17116  case OMPC_use_device_addr:
17117  case OMPC_is_device_ptr:
17118  case OMPC_has_device_addr:
17119  case OMPC_unified_address:
17120  case OMPC_unified_shared_memory:
17121  case OMPC_reverse_offload:
17122  case OMPC_dynamic_allocators:
17123  case OMPC_atomic_default_mem_order:
17124  case OMPC_device_type:
17125  case OMPC_match:
17126  case OMPC_nontemporal:
17127  case OMPC_at:
17128  case OMPC_severity:
17129  case OMPC_message:
17130  case OMPC_destroy:
17131  case OMPC_novariants:
17132  case OMPC_nocontext:
17133  case OMPC_detach:
17134  case OMPC_inclusive:
17135  case OMPC_exclusive:
17136  case OMPC_uses_allocators:
17137  case OMPC_affinity:
17138  case OMPC_when:
17139  case OMPC_bind:
17140  default:
17141  llvm_unreachable("Clause is not allowed.");
17142  }
17143  return Res;
17144 }
17145 
17148  SourceLocation M1Loc, SourceLocation M2Loc) {
17149  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17150  SmallVector<unsigned, 2> Excluded;
17152  Excluded.push_back(M2);
17153  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17154  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17155  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17156  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17157  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17158  << getListOfPossibleValues(OMPC_schedule,
17159  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17160  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17161  Excluded)
17162  << getOpenMPClauseName(OMPC_schedule);
17163  return true;
17164  }
17165  return false;
17166 }
17167 
17170  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17171  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17172  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17173  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17174  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17175  return nullptr;
17176  // OpenMP, 2.7.1, Loop Construct, Restrictions
17177  // Either the monotonic modifier or the nonmonotonic modifier can be specified
17178  // but not both.
17179  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17180  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17181  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17182  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17183  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17184  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17185  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17186  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17187  return nullptr;
17188  }
17189  if (Kind == OMPC_SCHEDULE_unknown) {
17190  std::string Values;
17191  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17192  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17193  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17194  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17195  Exclude);
17196  } else {
17197  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17198  /*Last=*/OMPC_SCHEDULE_unknown);
17199  }
17200  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17201  << Values << getOpenMPClauseName(OMPC_schedule);
17202  return nullptr;
17203  }
17204  // OpenMP, 2.7.1, Loop Construct, Restrictions
17205  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17206  // schedule(guided).
17207  // OpenMP 5.0 does not have this restriction.
17208  if (LangOpts.OpenMP < 50 &&
17209  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17210  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17211  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17212  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17213  diag::err_omp_schedule_nonmonotonic_static);
17214  return nullptr;
17215  }
17216  Expr *ValExpr = ChunkSize;
17217  Stmt *HelperValStmt = nullptr;
17218  if (ChunkSize) {
17219  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17220  !ChunkSize->isInstantiationDependent() &&
17221  !ChunkSize->containsUnexpandedParameterPack()) {
17222  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17223  ExprResult Val =
17224  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17225  if (Val.isInvalid())
17226  return nullptr;
17227 
17228  ValExpr = Val.get();
17229 
17230  // OpenMP [2.7.1, Restrictions]
17231  // chunk_size must be a loop invariant integer expression with a positive
17232  // value.
17233  if (std::optional<llvm::APSInt> Result =
17234  ValExpr->getIntegerConstantExpr(Context)) {
17235  if (Result->isSigned() && !Result->isStrictlyPositive()) {
17236  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17237  << "schedule" << 1 << ChunkSize->getSourceRange();
17238  return nullptr;
17239  }
17241  DSAStack->getCurrentDirective(), OMPC_schedule,
17242  LangOpts.OpenMP) != OMPD_unknown &&
17244  ValExpr = MakeFullExpr(ValExpr).get();
17245  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17246  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17247  HelperValStmt = buildPreInits(Context, Captures);
17248  }
17249  }
17250  }
17251 
17252  return new (Context)
17253  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17254  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17255 }
17256 
17258  SourceLocation StartLoc,
17259  SourceLocation EndLoc) {
17260  OMPClause *Res = nullptr;
17261  switch (Kind) {
17262  case OMPC_ordered:
17263  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17264  break;
17265  case OMPC_nowait:
17266  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17267  break;
17268  case OMPC_untied:
17269  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17270  break;
17271  case OMPC_mergeable:
17272  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17273  break;
17274  case OMPC_read:
17275  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17276  break;
17277  case OMPC_write:
17278  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17279  break;
17280  case OMPC_update:
17281  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17282  break;
17283  case OMPC_capture:
17284  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17285  break;
17286  case OMPC_compare:
17287  Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17288  break;
17289  case OMPC_seq_cst:
17290  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17291  break;
17292  case OMPC_acq_rel:
17293  Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17294  break;
17295  case OMPC_acquire:
17296  Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17297  break;
17298  case OMPC_release:
17299  Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17300  break;
17301  case OMPC_relaxed:
17302  Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17303  break;
17304  case OMPC_threads:
17305  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17306  break;
17307  case OMPC_simd:
17308  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17309  break;
17310  case OMPC_nogroup:
17311  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17312  break;
17313  case OMPC_unified_address:
17314  Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17315  break;
17316  case OMPC_unified_shared_memory:
17317  Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17318  break;
17319  case OMPC_reverse_offload:
17320  Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17321  break;
17322  case OMPC_dynamic_allocators:
17323  Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17324  break;
17325  case OMPC_destroy:
17326  Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17327  /*LParenLoc=*/SourceLocation(),
17328  /*VarLoc=*/SourceLocation(), EndLoc);
17329  break;
17330  case OMPC_full:
17331  Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17332  break;
17333  case OMPC_partial:
17334  Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17335  break;
17336  case OMPC_if:
17337  case OMPC_final:
17338  case OMPC_num_threads:
17339  case OMPC_safelen:
17340  case OMPC_simdlen:
17341  case OMPC_sizes:
17342  case OMPC_allocator:
17343  case OMPC_collapse:
17344  case OMPC_schedule:
17345  case OMPC_private:
17346  case OMPC_firstprivate:
17347  case OMPC_lastprivate:
17348  case OMPC_shared:
17349  case OMPC_reduction:
17350  case OMPC_task_reduction:
17351  case OMPC_in_reduction:
17352  case OMPC_linear:
17353  case OMPC_aligned:
17354  case OMPC_copyin:
17355  case OMPC_copyprivate:
17356  case OMPC_default:
17357  case OMPC_proc_bind:
17358  case OMPC_threadprivate:
17359  case OMPC_allocate:
17360  case OMPC_flush:
17361  case OMPC_depobj:
17362  case OMPC_depend:
17363  case OMPC_device:
17364  case OMPC_map:
17365  case OMPC_num_teams:
17366  case OMPC_thread_limit:
17367  case OMPC_priority:
17368  case OMPC_grainsize:
17369  case OMPC_num_tasks:
17370  case OMPC_hint:
17371  case OMPC_dist_schedule:
17372  case OMPC_defaultmap:
17373  case OMPC_unknown:
17374  case OMPC_uniform:
17375  case OMPC_to:
17376  case OMPC_from:
17377  case OMPC_use_device_ptr:
17378  case OMPC_use_device_addr:
17379  case OMPC_is_device_ptr:
17380  case OMPC_has_device_addr:
17381  case OMPC_atomic_default_mem_order:
17382  case OMPC_device_type:
17383  case OMPC_match:
17384  case OMPC_nontemporal:
17385  case OMPC_order:
17386  case OMPC_at:
17387  case OMPC_severity:
17388  case OMPC_message:
17389  case OMPC_novariants:
17390  case OMPC_nocontext:
17391  case OMPC_detach:
17392  case OMPC_inclusive:
17393  case OMPC_exclusive:
17394  case OMPC_uses_allocators:
17395  case OMPC_affinity:
17396  case OMPC_when:
17397  case OMPC_ompx_dyn_cgroup_mem:
17398  default:
17399  llvm_unreachable("Clause is not allowed.");
17400  }
17401  return Res;
17402 }
17403 
17405  SourceLocation EndLoc) {
17406  DSAStack->setNowaitRegion();
17407  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17408 }
17409 
17411  SourceLocation EndLoc) {
17412  DSAStack->setUntiedRegion();
17413  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17414 }
17415 
17417  SourceLocation EndLoc) {
17418  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17419 }
17420 
17422  SourceLocation EndLoc) {
17423  return new (Context) OMPReadClause(StartLoc, EndLoc);
17424 }
17425 
17427  SourceLocation EndLoc) {
17428  return new (Context) OMPWriteClause(StartLoc, EndLoc);
17429 }
17430 
17432  SourceLocation EndLoc) {
17433  return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17434 }
17435 
17437  SourceLocation EndLoc) {
17438  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17439 }
17440 
17442  SourceLocation EndLoc) {
17443  return new (Context) OMPCompareClause(StartLoc, EndLoc);
17444 }
17445 
17447  SourceLocation EndLoc) {
17448  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17449 }
17450 
17452  SourceLocation EndLoc) {
17453  return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17454 }
17455 
17457  SourceLocation EndLoc) {
17458  return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17459 }
17460 
17462  SourceLocation EndLoc) {
17463  return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17464 }
17465 
17467  SourceLocation EndLoc) {
17468  return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17469 }
17470 
17472  SourceLocation EndLoc) {
17473  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17474 }
17475 
17477  SourceLocation EndLoc) {
17478  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17479 }
17480 
17482  SourceLocation EndLoc) {
17483  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17484 }
17485 
17487  SourceLocation EndLoc) {
17488  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17489 }
17490 
17492  SourceLocation EndLoc) {
17493  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17494 }
17495 
17497  SourceLocation EndLoc) {
17498  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17499 }
17500 
17502  SourceLocation EndLoc) {
17503  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17504 }
17505 
17507  SourceLocation StartLoc,
17508  SourceLocation EndLoc) {
17509 
17510  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17511  // At least one action-clause must appear on a directive.
17512  if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17513  StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17514  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17515  << Expected << getOpenMPDirectiveName(OMPD_interop);
17516  return StmtError();
17517  }
17518 
17519  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17520  // A depend clause can only appear on the directive if a targetsync
17521  // interop-type is present or the interop-var was initialized with
17522  // the targetsync interop-type.
17523 
17524  // If there is any 'init' clause diagnose if there is no 'init' clause with
17525  // interop-type of 'targetsync'. Cases involving other directives cannot be
17526  // diagnosed.
17527  const OMPDependClause *DependClause = nullptr;
17528  bool HasInitClause = false;
17529  bool IsTargetSync = false;
17530  for (const OMPClause *C : Clauses) {
17531  if (IsTargetSync)
17532  break;
17533  if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17534  HasInitClause = true;
17535  if (InitClause->getIsTargetSync())
17536  IsTargetSync = true;
17537  } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17538  DependClause = DC;
17539  }
17540  }
17541  if (DependClause && HasInitClause && !IsTargetSync) {
17542  Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17543  return StmtError();
17544  }
17545 
17546  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17547  // Each interop-var may be specified for at most one action-clause of each
17548  // interop construct.
17550  for (OMPClause *C : Clauses) {
17551  OpenMPClauseKind ClauseKind = C->getClauseKind();
17552  std::pair<ValueDecl *, bool> DeclResult;
17553  SourceLocation ELoc;
17554  SourceRange ERange;
17555 
17556  if (ClauseKind == OMPC_init) {
17557  auto *E = cast<OMPInitClause>(C)->getInteropVar();
17558  DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17559  } else if (ClauseKind == OMPC_use) {
17560  auto *E = cast<OMPUseClause>(C)->getInteropVar();
17561  DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17562  } else if (ClauseKind == OMPC_destroy) {
17563  auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17564  DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17565  }
17566 
17567  if (DeclResult.first) {
17568  if (!InteropVars.insert(DeclResult.first).second) {
17569  Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17570  << DeclResult.first;
17571  return StmtError();
17572  }
17573  }
17574  }
17575 
17576  return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17577 }
17578 
17579 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17580  SourceLocation VarLoc,
17582  SourceLocation ELoc;
17583  SourceRange ERange;
17584  Expr *RefExpr = InteropVarExpr;
17585  auto Res =
17586  getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17587  /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17588 
17589  if (Res.second) {
17590  // It will be analyzed later.
17591  return true;
17592  }
17593 
17594  if (!Res.first)
17595  return false;
17596 
17597  // Interop variable should be of type omp_interop_t.
17598  bool HasError = false;
17599  QualType InteropType;
17600  LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17601  VarLoc, Sema::LookupOrdinaryName);
17602  if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17603  NamedDecl *ND = Result.getFoundDecl();
17604  if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17605  InteropType = QualType(TD->getTypeForDecl(), 0);
17606  } else {
17607  HasError = true;
17608  }
17609  } else {
17610  HasError = true;
17611  }
17612 
17613  if (HasError) {
17614  SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17615  << "omp_interop_t";
17616  return false;
17617  }
17618 
17619  QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17620  if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17621  SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17622  return false;
17623  }
17624 
17625  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17626  // The interop-var passed to init or destroy must be non-const.
17627  if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17628  isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17629  SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17630  << /*non-const*/ 1;
17631  return false;
17632  }
17633  return true;
17634 }
17635 
17636 OMPClause *
17638  SourceLocation StartLoc, SourceLocation LParenLoc,
17639  SourceLocation VarLoc, SourceLocation EndLoc) {
17640 
17641  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17642  return nullptr;
17643 
17644  // Check prefer_type values. These foreign-runtime-id values are either
17645  // string literals or constant integral expressions.
17646  for (const Expr *E : InteropInfo.PreferTypes) {
17647  if (E->isValueDependent() || E->isTypeDependent() ||
17649  continue;
17651  continue;
17652  if (isa<StringLiteral>(E))
17653  continue;
17654  Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17655  return nullptr;
17656  }
17657 
17658  return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17659  LParenLoc, VarLoc, EndLoc);
17660 }
17661 
17663  SourceLocation LParenLoc,
17664  SourceLocation VarLoc,
17665  SourceLocation EndLoc) {
17666 
17667  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17668  return nullptr;
17669 
17670  return new (Context)
17671  OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17672 }
17673 
17675  SourceLocation StartLoc,
17676  SourceLocation LParenLoc,
17677  SourceLocation VarLoc,
17678  SourceLocation EndLoc) {
17679  if (!InteropVar && LangOpts.OpenMP >= 52 &&
17680  DSAStack->getCurrentDirective() == OMPD_depobj) {
17681  Diag(StartLoc, diag::err_omp_expected_clause_argument)
17682  << getOpenMPClauseName(OMPC_destroy)
17683  << getOpenMPDirectiveName(OMPD_depobj);
17684  return nullptr;
17685  }
17686  if (InteropVar &&
17687  !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
17688  return nullptr;
17689 
17690  return new (Context)
17691  OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17692 }
17693 
17695  SourceLocation StartLoc,
17696  SourceLocation LParenLoc,
17697  SourceLocation EndLoc) {
17698  Expr *ValExpr = Condition;
17699  Stmt *HelperValStmt = nullptr;
17700  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17701  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17702  !Condition->isInstantiationDependent() &&
17703  !Condition->containsUnexpandedParameterPack()) {
17704  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17705  if (Val.isInvalid())
17706  return nullptr;
17707 
17708  ValExpr = MakeFullExpr(Val.get()).get();
17709 
17710  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17711  CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17712  LangOpts.OpenMP);
17713  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17714  ValExpr = MakeFullExpr(ValExpr).get();
17715  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17716  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17717  HelperValStmt = buildPreInits(Context, Captures);
17718  }
17719  }
17720 
17721  return new (Context) OMPNovariantsClause(
17722  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17723 }
17724 
17726  SourceLocation StartLoc,
17727  SourceLocation LParenLoc,
17728  SourceLocation EndLoc) {
17729  Expr *ValExpr = Condition;
17730  Stmt *HelperValStmt = nullptr;
17731  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17732  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17733  !Condition->isInstantiationDependent() &&
17734  !Condition->containsUnexpandedParameterPack()) {
17735  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17736  if (Val.isInvalid())
17737  return nullptr;
17738 
17739  ValExpr = MakeFullExpr(Val.get()).get();
17740 
17741  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17742  CaptureRegion =
17743  getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
17744  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17745  ValExpr = MakeFullExpr(ValExpr).get();
17746  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17747  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17748  HelperValStmt = buildPreInits(Context, Captures);
17749  }
17750  }
17751 
17752  return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
17753  StartLoc, LParenLoc, EndLoc);
17754 }
17755 
17757  SourceLocation StartLoc,
17758  SourceLocation LParenLoc,
17759  SourceLocation EndLoc) {
17760  Expr *ValExpr = ThreadID;
17761  Stmt *HelperValStmt = nullptr;
17762 
17763  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17764  OpenMPDirectiveKind CaptureRegion =
17765  getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
17766  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17767  ValExpr = MakeFullExpr(ValExpr).get();
17768  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17769  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17770  HelperValStmt = buildPreInits(Context, Captures);
17771  }
17772 
17773  return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
17774  StartLoc, LParenLoc, EndLoc);
17775 }
17776 
17778  ArrayRef<Expr *> VarList,
17779  const OMPVarListLocTy &Locs,
17781  SourceLocation StartLoc = Locs.StartLoc;
17782  SourceLocation LParenLoc = Locs.LParenLoc;
17783  SourceLocation EndLoc = Locs.EndLoc;
17784  OMPClause *Res = nullptr;
17785  int ExtraModifier = Data.ExtraModifier;
17786  SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
17787  SourceLocation ColonLoc = Data.ColonLoc;
17788  switch (Kind) {
17789  case OMPC_private:
17790  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17791  break;
17792  case OMPC_firstprivate:
17793  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17794  break;
17795  case OMPC_lastprivate:
17796  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
17797  "Unexpected lastprivate modifier.");
17799  VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
17800  ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17801  break;
17802  case OMPC_shared:
17803  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
17804  break;
17805  case OMPC_reduction:
17806  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
17807  "Unexpected lastprivate modifier.");
17809  VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
17810  StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17811  Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17812  break;
17813  case OMPC_task_reduction:
17815  VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17816  Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17817  break;
17818  case OMPC_in_reduction:
17820  VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17821  Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17822  break;
17823  case OMPC_linear:
17824  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
17825  "Unexpected linear modifier.");
17827  VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
17828  static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
17829  ColonLoc, EndLoc);
17830  break;
17831  case OMPC_aligned:
17832  Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
17833  LParenLoc, ColonLoc, EndLoc);
17834  break;
17835  case OMPC_copyin:
17836  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
17837  break;
17838  case OMPC_copyprivate:
17839  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17840  break;
17841  case OMPC_flush:
17842  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
17843  break;
17844  case OMPC_depend:
17845  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
17846  "Unexpected depend modifier.");
17848  {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
17849  ColonLoc, Data.OmpAllMemoryLoc},
17850  Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
17851  break;
17852  case OMPC_map:
17853  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
17854  "Unexpected map modifier.");
17855  Res = ActOnOpenMPMapClause(
17856  Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
17857  Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
17858  static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
17859  ExtraModifierLoc, ColonLoc, VarList, Locs);
17860  break;
17861  case OMPC_to:
17862  Res =
17863  ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17864  Data.ReductionOrMapperIdScopeSpec,
17865  Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
17866  break;
17867  case OMPC_from:
17868  Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17869  Data.ReductionOrMapperIdScopeSpec,
17870  Data.ReductionOrMapperId, ColonLoc, VarList,
17871  Locs);
17872  break;
17873  case OMPC_use_device_ptr:
17874  Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17875  break;
17876  case OMPC_use_device_addr:
17877  Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17878  break;
17879  case OMPC_is_device_ptr:
17880  Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17881  break;
17882  case OMPC_has_device_addr:
17883  Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17884  break;
17885  case OMPC_allocate:
17886  Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
17887  LParenLoc, ColonLoc, EndLoc);
17888  break;
17889  case OMPC_nontemporal:
17890  Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17891  break;
17892  case OMPC_inclusive:
17893  Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17894  break;
17895  case OMPC_exclusive:
17896  Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17897  break;
17898  case OMPC_affinity:
17899  Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17900  Data.DepModOrTailExpr, VarList);
17901  break;
17902  case OMPC_if:
17903  case OMPC_depobj:
17904  case OMPC_final:
17905  case OMPC_num_threads:
17906  case OMPC_safelen:
17907  case OMPC_simdlen:
17908  case OMPC_sizes:
17909  case OMPC_allocator:
17910  case OMPC_collapse:
17911  case OMPC_default:
17912  case OMPC_proc_bind:
17913  case OMPC_schedule:
17914  case OMPC_ordered:
17915  case OMPC_nowait:
17916  case OMPC_untied:
17917  case OMPC_mergeable:
17918  case OMPC_threadprivate:
17919  case OMPC_read:
17920  case OMPC_write:
17921  case OMPC_update:
17922  case OMPC_capture:
17923  case OMPC_compare:
17924  case OMPC_seq_cst:
17925  case OMPC_acq_rel:
17926  case OMPC_acquire:
17927  case OMPC_release:
17928  case OMPC_relaxed:
17929  case OMPC_device:
17930  case OMPC_threads:
17931  case OMPC_simd:
17932  case OMPC_num_teams:
17933  case OMPC_thread_limit:
17934  case OMPC_priority:
17935  case OMPC_grainsize:
17936  case OMPC_nogroup:
17937  case OMPC_num_tasks:
17938  case OMPC_hint:
17939  case OMPC_dist_schedule:
17940  case OMPC_defaultmap:
17941  case OMPC_unknown:
17942  case OMPC_uniform:
17943  case OMPC_unified_address:
17944  case OMPC_unified_shared_memory:
17945  case OMPC_reverse_offload:
17946  case OMPC_dynamic_allocators:
17947  case OMPC_atomic_default_mem_order:
17948  case OMPC_device_type:
17949  case OMPC_match:
17950  case OMPC_order:
17951  case OMPC_at:
17952  case OMPC_severity:
17953  case OMPC_message:
17954  case OMPC_destroy:
17955  case OMPC_novariants:
17956  case OMPC_nocontext:
17957  case OMPC_detach:
17958  case OMPC_uses_allocators:
17959  case OMPC_when:
17960  case OMPC_bind:
17961  default:
17962  llvm_unreachable("Clause is not allowed.");
17963  }
17964  return Res;
17965 }
17966 
17968  ExprObjectKind OK, SourceLocation Loc) {
17970  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17971  if (!Res.isUsable())
17972  return ExprError();
17973  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17974  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17975  if (!Res.isUsable())
17976  return ExprError();
17977  }
17978  if (VK != VK_LValue && Res.get()->isGLValue()) {
17979  Res = DefaultLvalueConversion(Res.get());
17980  if (!Res.isUsable())
17981  return ExprError();
17982  }
17983  return Res;
17984 }
17985 
17987  SourceLocation StartLoc,
17988  SourceLocation LParenLoc,
17989  SourceLocation EndLoc) {
17991  SmallVector<Expr *, 8> PrivateCopies;
17992  bool IsImplicitClause =
17993  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17994  for (Expr *RefExpr : VarList) {
17995  assert(RefExpr && "NULL expr in OpenMP private clause.");
17996  SourceLocation ELoc;
17997  SourceRange ERange;
17998  Expr *SimpleRefExpr = RefExpr;
17999  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18000  if (Res.second) {
18001  // It will be analyzed later.
18002  Vars.push_back(RefExpr);
18003  PrivateCopies.push_back(nullptr);
18004  }
18005  ValueDecl *D = Res.first;
18006  if (!D)
18007  continue;
18008 
18009  QualType Type = D->getType();
18010  auto *VD = dyn_cast<VarDecl>(D);
18011 
18012  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18013  // A variable that appears in a private clause must not have an incomplete
18014  // type or a reference type.
18015  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18016  continue;
18017  Type = Type.getNonReferenceType();
18018 
18019  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18020  // A variable that is privatized must not have a const-qualified type
18021  // unless it is of class type with a mutable member. This restriction does
18022  // not apply to the firstprivate clause.
18023  //
18024  // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18025  // A variable that appears in a private clause must not have a
18026  // const-qualified type unless it is of class type with a mutable member.
18027  if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18028  continue;
18029 
18030  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18031  // in a Construct]
18032  // Variables with the predetermined data-sharing attributes may not be
18033  // listed in data-sharing attributes clauses, except for the cases
18034  // listed below. For these exceptions only, listing a predetermined
18035  // variable in a data-sharing attribute clause is allowed and overrides
18036  // the variable's predetermined data-sharing attributes.
18037  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18038  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18039  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18040  << getOpenMPClauseName(OMPC_private);
18041  reportOriginalDsa(*this, DSAStack, D, DVar);
18042  continue;
18043  }
18044 
18045  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18046  // Variably modified types are not supported for tasks.
18048  isOpenMPTaskingDirective(CurrDir)) {
18049  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18050  << getOpenMPClauseName(OMPC_private) << Type
18051  << getOpenMPDirectiveName(CurrDir);
18052  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18054  Diag(D->getLocation(),
18055  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18056  << D;
18057  continue;
18058  }
18059 
18060  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18061  // A list item cannot appear in both a map clause and a data-sharing
18062  // attribute clause on the same construct
18063  //
18064  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18065  // A list item cannot appear in both a map clause and a data-sharing
18066  // attribute clause on the same construct unless the construct is a
18067  // combined construct.
18068  if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
18069  CurrDir == OMPD_target) {
18070  OpenMPClauseKind ConflictKind;
18071  if (DSAStack->checkMappableExprComponentListsForDecl(
18072  VD, /*CurrentRegionOnly=*/true,
18074  OpenMPClauseKind WhereFoundClauseKind) -> bool {
18075  ConflictKind = WhereFoundClauseKind;
18076  return true;
18077  })) {
18078  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18079  << getOpenMPClauseName(OMPC_private)
18080  << getOpenMPClauseName(ConflictKind)
18081  << getOpenMPDirectiveName(CurrDir);
18082  reportOriginalDsa(*this, DSAStack, D, DVar);
18083  continue;
18084  }
18085  }
18086 
18087  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18088  // A variable of class type (or array thereof) that appears in a private
18089  // clause requires an accessible, unambiguous default constructor for the
18090  // class type.
18091  // Generate helper private variable and initialize it with the default
18092  // value. The address of the original variable is replaced by the address of
18093  // the new private variable in CodeGen. This new variable is not added to
18094  // IdResolver, so the code in the OpenMP region uses original variable for
18095  // proper diagnostics.
18096  Type = Type.getUnqualifiedType();
18097  VarDecl *VDPrivate =
18098  buildVarDecl(*this, ELoc, Type, D->getName(),
18099  D->hasAttrs() ? &D->getAttrs() : nullptr,
18100  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18101  ActOnUninitializedDecl(VDPrivate);
18102  if (VDPrivate->isInvalidDecl())
18103  continue;
18104  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18105  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18106 
18107  DeclRefExpr *Ref = nullptr;
18108  if (!VD && !CurContext->isDependentContext()) {
18109  auto *FD = dyn_cast<FieldDecl>(D);
18110  VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18111  if (VD)
18112  Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18113  RefExpr->getExprLoc());
18114  else
18115  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18116  }
18117  if (!IsImplicitClause)
18118  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18119  Vars.push_back((VD || CurContext->isDependentContext())
18120  ? RefExpr->IgnoreParens()
18121  : Ref);
18122  PrivateCopies.push_back(VDPrivateRefExpr);
18123  }
18124 
18125  if (Vars.empty())
18126  return nullptr;
18127 
18128  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18129  PrivateCopies);
18130 }
18131 
18133  SourceLocation StartLoc,
18134  SourceLocation LParenLoc,
18135  SourceLocation EndLoc) {
18137  SmallVector<Expr *, 8> PrivateCopies;
18138  SmallVector<Expr *, 8> Inits;
18139  SmallVector<Decl *, 4> ExprCaptures;
18140  bool IsImplicitClause =
18141  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18142  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18143 
18144  for (Expr *RefExpr : VarList) {
18145  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18146  SourceLocation ELoc;
18147  SourceRange ERange;
18148  Expr *SimpleRefExpr = RefExpr;
18149  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18150  if (Res.second) {
18151  // It will be analyzed later.
18152  Vars.push_back(RefExpr);
18153  PrivateCopies.push_back(nullptr);
18154  Inits.push_back(nullptr);
18155  }
18156  ValueDecl *D = Res.first;
18157  if (!D)
18158  continue;
18159 
18160  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18161  QualType Type = D->getType();
18162  auto *VD = dyn_cast<VarDecl>(D);
18163 
18164  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18165  // A variable that appears in a private clause must not have an incomplete
18166  // type or a reference type.
18167  if (RequireCompleteType(ELoc, Type,
18168  diag::err_omp_firstprivate_incomplete_type))
18169  continue;
18170  Type = Type.getNonReferenceType();
18171 
18172  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18173  // A variable of class type (or array thereof) that appears in a private
18174  // clause requires an accessible, unambiguous copy constructor for the
18175  // class type.
18177 
18178  // If an implicit firstprivate variable found it was checked already.
18179  DSAStackTy::DSAVarData TopDVar;
18180  if (!IsImplicitClause) {
18181  DSAStackTy::DSAVarData DVar =
18182  DSAStack->getTopDSA(D, /*FromParent=*/false);
18183  TopDVar = DVar;
18184  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18185  bool IsConstant = ElemType.isConstant(Context);
18186  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18187  // A list item that specifies a given variable may not appear in more
18188  // than one clause on the same directive, except that a variable may be
18189  // specified in both firstprivate and lastprivate clauses.
18190  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18191  // A list item may appear in a firstprivate or lastprivate clause but not
18192  // both.
18193  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18194  (isOpenMPDistributeDirective(CurrDir) ||
18195  DVar.CKind != OMPC_lastprivate) &&
18196  DVar.RefExpr) {
18197  Diag(ELoc, diag::err_omp_wrong_dsa)
18198  << getOpenMPClauseName(DVar.CKind)
18199  << getOpenMPClauseName(OMPC_firstprivate);
18200  reportOriginalDsa(*this, DSAStack, D, DVar);
18201  continue;
18202  }
18203 
18204  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18205  // in a Construct]
18206  // Variables with the predetermined data-sharing attributes may not be
18207  // listed in data-sharing attributes clauses, except for the cases
18208  // listed below. For these exceptions only, listing a predetermined
18209  // variable in a data-sharing attribute clause is allowed and overrides
18210  // the variable's predetermined data-sharing attributes.
18211  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18212  // in a Construct, C/C++, p.2]
18213  // Variables with const-qualified type having no mutable member may be
18214  // listed in a firstprivate clause, even if they are static data members.
18215  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18216  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18217  Diag(ELoc, diag::err_omp_wrong_dsa)
18218  << getOpenMPClauseName(DVar.CKind)
18219  << getOpenMPClauseName(OMPC_firstprivate);
18220  reportOriginalDsa(*this, DSAStack, D, DVar);
18221  continue;
18222  }
18223 
18224  // OpenMP [2.9.3.4, Restrictions, p.2]
18225  // A list item that is private within a parallel region must not appear
18226  // in a firstprivate clause on a worksharing construct if any of the
18227  // worksharing regions arising from the worksharing construct ever bind
18228  // to any of the parallel regions arising from the parallel construct.
18229  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18230  // A list item that is private within a teams region must not appear in a
18231  // firstprivate clause on a distribute construct if any of the distribute
18232  // regions arising from the distribute construct ever bind to any of the
18233  // teams regions arising from the teams construct.
18234  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18235  // A list item that appears in a reduction clause of a teams construct
18236  // must not appear in a firstprivate clause on a distribute construct if
18237  // any of the distribute regions arising from the distribute construct
18238  // ever bind to any of the teams regions arising from the teams construct.
18239  if ((isOpenMPWorksharingDirective(CurrDir) ||
18240  isOpenMPDistributeDirective(CurrDir)) &&
18241  !isOpenMPParallelDirective(CurrDir) &&
18242  !isOpenMPTeamsDirective(CurrDir)) {
18243  DVar = DSAStack->getImplicitDSA(D, true);
18244  if (DVar.CKind != OMPC_shared &&
18245  (isOpenMPParallelDirective(DVar.DKind) ||
18246  isOpenMPTeamsDirective(DVar.DKind) ||
18247  DVar.DKind == OMPD_unknown)) {
18248  Diag(ELoc, diag::err_omp_required_access)
18249  << getOpenMPClauseName(OMPC_firstprivate)
18250  << getOpenMPClauseName(OMPC_shared);
18251  reportOriginalDsa(*this, DSAStack, D, DVar);
18252  continue;
18253  }
18254  }
18255  // OpenMP [2.9.3.4, Restrictions, p.3]
18256  // A list item that appears in a reduction clause of a parallel construct
18257  // must not appear in a firstprivate clause on a worksharing or task
18258  // construct if any of the worksharing or task regions arising from the
18259  // worksharing or task construct ever bind to any of the parallel regions
18260  // arising from the parallel construct.
18261  // OpenMP [2.9.3.4, Restrictions, p.4]
18262  // A list item that appears in a reduction clause in worksharing
18263  // construct must not appear in a firstprivate clause in a task construct
18264  // encountered during execution of any of the worksharing regions arising
18265  // from the worksharing construct.
18266  if (isOpenMPTaskingDirective(CurrDir)) {
18267  DVar = DSAStack->hasInnermostDSA(
18268  D,
18269  [](OpenMPClauseKind C, bool AppliedToPointee) {
18270  return C == OMPC_reduction && !AppliedToPointee;
18271  },
18272  [](OpenMPDirectiveKind K) {
18273  return isOpenMPParallelDirective(K) ||
18276  },
18277  /*FromParent=*/true);
18278  if (DVar.CKind == OMPC_reduction &&
18279  (isOpenMPParallelDirective(DVar.DKind) ||
18280  isOpenMPWorksharingDirective(DVar.DKind) ||
18281  isOpenMPTeamsDirective(DVar.DKind))) {
18282  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18283  << getOpenMPDirectiveName(DVar.DKind);
18284  reportOriginalDsa(*this, DSAStack, D, DVar);
18285  continue;
18286  }
18287  }
18288 
18289  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18290  // A list item cannot appear in both a map clause and a data-sharing
18291  // attribute clause on the same construct
18292  //
18293  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18294  // A list item cannot appear in both a map clause and a data-sharing
18295  // attribute clause on the same construct unless the construct is a
18296  // combined construct.
18297  if ((LangOpts.OpenMP <= 45 &&
18299  CurrDir == OMPD_target) {
18300  OpenMPClauseKind ConflictKind;
18301  if (DSAStack->checkMappableExprComponentListsForDecl(
18302  VD, /*CurrentRegionOnly=*/true,
18303  [&ConflictKind](
18305  OpenMPClauseKind WhereFoundClauseKind) {
18306  ConflictKind = WhereFoundClauseKind;
18307  return true;
18308  })) {
18309  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18310  << getOpenMPClauseName(OMPC_firstprivate)
18311  << getOpenMPClauseName(ConflictKind)
18312  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18313  reportOriginalDsa(*this, DSAStack, D, DVar);
18314  continue;
18315  }
18316  }
18317  }
18318 
18319  // Variably modified types are not supported for tasks.
18321  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18322  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18323  << getOpenMPClauseName(OMPC_firstprivate) << Type
18324  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18325  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18327  Diag(D->getLocation(),
18328  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18329  << D;
18330  continue;
18331  }
18332 
18333  Type = Type.getUnqualifiedType();
18334  VarDecl *VDPrivate =
18335  buildVarDecl(*this, ELoc, Type, D->getName(),
18336  D->hasAttrs() ? &D->getAttrs() : nullptr,
18337  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18338  // Generate helper private variable and initialize it with the value of the
18339  // original variable. The address of the original variable is replaced by
18340  // the address of the new private variable in the CodeGen. This new variable
18341  // is not added to IdResolver, so the code in the OpenMP region uses
18342  // original variable for proper diagnostics and variable capturing.
18343  Expr *VDInitRefExpr = nullptr;
18344  // For arrays generate initializer for single element and replace it by the
18345  // original array element in CodeGen.
18346  if (Type->isArrayType()) {
18347  VarDecl *VDInit =
18348  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18349  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18350  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18351  ElemType = ElemType.getUnqualifiedType();
18352  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18353  ".firstprivate.temp");
18354  InitializedEntity Entity =
18357 
18358  InitializationSequence InitSeq(*this, Entity, Kind, Init);
18359  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18360  if (Result.isInvalid())
18361  VDPrivate->setInvalidDecl();
18362  else
18363  VDPrivate->setInit(Result.getAs<Expr>());
18364  // Remove temp variable declaration.
18365  Context.Deallocate(VDInitTemp);
18366  } else {
18367  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18368  ".firstprivate.temp");
18369  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18370  RefExpr->getExprLoc());
18371  AddInitializerToDecl(VDPrivate,
18372  DefaultLvalueConversion(VDInitRefExpr).get(),
18373  /*DirectInit=*/false);
18374  }
18375  if (VDPrivate->isInvalidDecl()) {
18376  if (IsImplicitClause) {
18377  Diag(RefExpr->getExprLoc(),
18378  diag::note_omp_task_predetermined_firstprivate_here);
18379  }
18380  continue;
18381  }
18382  CurContext->addDecl(VDPrivate);
18383  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18384  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18385  RefExpr->getExprLoc());
18386  DeclRefExpr *Ref = nullptr;
18387  if (!VD && !CurContext->isDependentContext()) {
18388  if (TopDVar.CKind == OMPC_lastprivate) {
18389  Ref = TopDVar.PrivateCopy;
18390  } else {
18391  auto *FD = dyn_cast<FieldDecl>(D);
18392  VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18393  if (VD)
18394  Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18395  RefExpr->getExprLoc());
18396  else
18397  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18398  if (VD || !isOpenMPCapturedDecl(D))
18399  ExprCaptures.push_back(Ref->getDecl());
18400  }
18401  }
18402  if (!IsImplicitClause)
18403  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18404  Vars.push_back((VD || CurContext->isDependentContext())
18405  ? RefExpr->IgnoreParens()
18406  : Ref);
18407  PrivateCopies.push_back(VDPrivateRefExpr);
18408  Inits.push_back(VDInitRefExpr);
18409  }
18410 
18411  if (Vars.empty())
18412  return nullptr;
18413 
18414  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18415  Vars, PrivateCopies, Inits,
18416  buildPreInits(Context, ExprCaptures));
18417 }
18418 
18421  SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18422  SourceLocation LParenLoc, SourceLocation EndLoc) {
18423  if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18424  assert(ColonLoc.isValid() && "Colon location must be valid.");
18425  Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18426  << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18427  /*Last=*/OMPC_LASTPRIVATE_unknown)
18428  << getOpenMPClauseName(OMPC_lastprivate);
18429  return nullptr;
18430  }
18431 
18433  SmallVector<Expr *, 8> SrcExprs;
18434  SmallVector<Expr *, 8> DstExprs;
18435  SmallVector<Expr *, 8> AssignmentOps;
18436  SmallVector<Decl *, 4> ExprCaptures;
18437  SmallVector<Expr *, 4> ExprPostUpdates;
18438  for (Expr *RefExpr : VarList) {
18439  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18440  SourceLocation ELoc;
18441  SourceRange ERange;
18442  Expr *SimpleRefExpr = RefExpr;
18443  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18444  if (Res.second) {
18445  // It will be analyzed later.
18446  Vars.push_back(RefExpr);
18447  SrcExprs.push_back(nullptr);
18448  DstExprs.push_back(nullptr);
18449  AssignmentOps.push_back(nullptr);
18450  }
18451  ValueDecl *D = Res.first;
18452  if (!D)
18453  continue;
18454 
18455  QualType Type = D->getType();
18456  auto *VD = dyn_cast<VarDecl>(D);
18457 
18458  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18459  // A variable that appears in a lastprivate clause must not have an
18460  // incomplete type or a reference type.
18461  if (RequireCompleteType(ELoc, Type,
18462  diag::err_omp_lastprivate_incomplete_type))
18463  continue;
18464  Type = Type.getNonReferenceType();
18465 
18466  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18467  // A variable that is privatized must not have a const-qualified type
18468  // unless it is of class type with a mutable member. This restriction does
18469  // not apply to the firstprivate clause.
18470  //
18471  // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18472  // A variable that appears in a lastprivate clause must not have a
18473  // const-qualified type unless it is of class type with a mutable member.
18474  if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18475  continue;
18476 
18477  // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18478  // A list item that appears in a lastprivate clause with the conditional
18479  // modifier must be a scalar variable.
18480  if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18481  Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18482  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18484  Diag(D->getLocation(),
18485  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18486  << D;
18487  continue;
18488  }
18489 
18490  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18491  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18492  // in a Construct]
18493  // Variables with the predetermined data-sharing attributes may not be
18494  // listed in data-sharing attributes clauses, except for the cases
18495  // listed below.
18496  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18497  // A list item may appear in a firstprivate or lastprivate clause but not
18498  // both.
18499  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18500  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18501  (isOpenMPDistributeDirective(CurrDir) ||
18502  DVar.CKind != OMPC_firstprivate) &&
18503  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18504  Diag(ELoc, diag::err_omp_wrong_dsa)
18505  << getOpenMPClauseName(DVar.CKind)
18506  << getOpenMPClauseName(OMPC_lastprivate);
18507  reportOriginalDsa(*this, DSAStack, D, DVar);
18508  continue;
18509  }
18510 
18511  // OpenMP [2.14.3.5, Restrictions, p.2]
18512  // A list item that is private within a parallel region, or that appears in
18513  // the reduction clause of a parallel construct, must not appear in a
18514  // lastprivate clause on a worksharing construct if any of the corresponding
18515  // worksharing regions ever binds to any of the corresponding parallel
18516  // regions.
18517  DSAStackTy::DSAVarData TopDVar = DVar;
18518  if (isOpenMPWorksharingDirective(CurrDir) &&
18519  !isOpenMPParallelDirective(CurrDir) &&
18520  !isOpenMPTeamsDirective(CurrDir)) {
18521  DVar = DSAStack->getImplicitDSA(D, true);
18522  if (DVar.CKind != OMPC_shared) {
18523  Diag(ELoc, diag::err_omp_required_access)
18524  << getOpenMPClauseName(OMPC_lastprivate)
18525  << getOpenMPClauseName(OMPC_shared);
18526  reportOriginalDsa(*this, DSAStack, D, DVar);
18527  continue;
18528  }
18529  }
18530 
18531  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18532  // A variable of class type (or array thereof) that appears in a
18533  // lastprivate clause requires an accessible, unambiguous default
18534  // constructor for the class type, unless the list item is also specified
18535  // in a firstprivate clause.
18536  // A variable of class type (or array thereof) that appears in a
18537  // lastprivate clause requires an accessible, unambiguous copy assignment
18538  // operator for the class type.
18540  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18541  Type.getUnqualifiedType(), ".lastprivate.src",
18542  D->hasAttrs() ? &D->getAttrs() : nullptr);
18543  DeclRefExpr *PseudoSrcExpr =
18544  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18545  VarDecl *DstVD =
18546  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18547  D->hasAttrs() ? &D->getAttrs() : nullptr);
18548  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18549  // For arrays generate assignment operation for single element and replace
18550  // it by the original array element in CodeGen.
18551  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18552  PseudoDstExpr, PseudoSrcExpr);
18553  if (AssignmentOp.isInvalid())
18554  continue;
18555  AssignmentOp =
18556  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18557  if (AssignmentOp.isInvalid())
18558  continue;
18559 
18560  DeclRefExpr *Ref = nullptr;
18561  if (!VD && !CurContext->isDependentContext()) {
18562  if (TopDVar.CKind == OMPC_firstprivate) {
18563  Ref = TopDVar.PrivateCopy;
18564  } else {
18565  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18566  if (!isOpenMPCapturedDecl(D))
18567  ExprCaptures.push_back(Ref->getDecl());
18568  }
18569  if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18570  (!isOpenMPCapturedDecl(D) &&
18571  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18572  ExprResult RefRes = DefaultLvalueConversion(Ref);
18573  if (!RefRes.isUsable())
18574  continue;
18575  ExprResult PostUpdateRes =
18576  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18577  RefRes.get());
18578  if (!PostUpdateRes.isUsable())
18579  continue;
18580  ExprPostUpdates.push_back(
18581  IgnoredValueConversions(PostUpdateRes.get()).get());
18582  }
18583  }
18584  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18585  Vars.push_back((VD || CurContext->isDependentContext())
18586  ? RefExpr->IgnoreParens()
18587  : Ref);
18588  SrcExprs.push_back(PseudoSrcExpr);
18589  DstExprs.push_back(PseudoDstExpr);
18590  AssignmentOps.push_back(AssignmentOp.get());
18591  }
18592 
18593  if (Vars.empty())
18594  return nullptr;
18595 
18596  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18597  Vars, SrcExprs, DstExprs, AssignmentOps,
18598  LPKind, LPKindLoc, ColonLoc,
18599  buildPreInits(Context, ExprCaptures),
18600  buildPostUpdate(*this, ExprPostUpdates));
18601 }
18602 
18604  SourceLocation StartLoc,
18605  SourceLocation LParenLoc,
18606  SourceLocation EndLoc) {
18608  for (Expr *RefExpr : VarList) {
18609  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18610  SourceLocation ELoc;
18611  SourceRange ERange;
18612  Expr *SimpleRefExpr = RefExpr;
18613  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18614  if (Res.second) {
18615  // It will be analyzed later.
18616  Vars.push_back(RefExpr);
18617  }
18618  ValueDecl *D = Res.first;
18619  if (!D)
18620  continue;
18621 
18622  auto *VD = dyn_cast<VarDecl>(D);
18623  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18624  // in a Construct]
18625  // Variables with the predetermined data-sharing attributes may not be
18626  // listed in data-sharing attributes clauses, except for the cases
18627  // listed below. For these exceptions only, listing a predetermined
18628  // variable in a data-sharing attribute clause is allowed and overrides
18629  // the variable's predetermined data-sharing attributes.
18630  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18631  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18632  DVar.RefExpr) {
18633  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18634  << getOpenMPClauseName(OMPC_shared);
18635  reportOriginalDsa(*this, DSAStack, D, DVar);
18636  continue;
18637  }
18638 
18639  DeclRefExpr *Ref = nullptr;
18640  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18641  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18642  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18643  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18644  ? RefExpr->IgnoreParens()
18645  : Ref);
18646  }
18647 
18648  if (Vars.empty())
18649  return nullptr;
18650 
18651  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18652 }
18653 
18654 namespace {
18655 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18656  DSAStackTy *Stack;
18657 
18658 public:
18659  bool VisitDeclRefExpr(DeclRefExpr *E) {
18660  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18661  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18662  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18663  return false;
18664  if (DVar.CKind != OMPC_unknown)
18665  return true;
18666  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18667  VD,
18668  [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18669  return isOpenMPPrivate(C) && !AppliedToPointee;
18670  },
18671  [](OpenMPDirectiveKind) { return true; },
18672  /*FromParent=*/true);
18673  return DVarPrivate.CKind != OMPC_unknown;
18674  }
18675  return false;
18676  }
18677  bool VisitStmt(Stmt *S) {
18678  for (Stmt *Child : S->children()) {
18679  if (Child && Visit(Child))
18680  return true;
18681  }
18682  return false;
18683  }
18684  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18685 };
18686 } // namespace
18687 
18688 namespace {
18689 // Transform MemberExpression for specified FieldDecl of current class to
18690 // DeclRefExpr to specified OMPCapturedExprDecl.
18691 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18692  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18693  ValueDecl *Field = nullptr;
18694  DeclRefExpr *CapturedExpr = nullptr;
18695 
18696 public:
18697  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18698  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18699 
18700  ExprResult TransformMemberExpr(MemberExpr *E) {
18701  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18702  E->getMemberDecl() == Field) {
18703  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18704  return CapturedExpr;
18705  }
18706  return BaseTransform::TransformMemberExpr(E);
18707  }
18708  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18709 };
18710 } // namespace
18711 
18712 template <typename T, typename U>
18714  SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18715  for (U &Set : Lookups) {
18716  for (auto *D : Set) {
18717  if (T Res = Gen(cast<ValueDecl>(D)))
18718  return Res;
18719  }
18720  }
18721  return T();
18722 }
18723 
18725  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
18726 
18727  for (auto *RD : D->redecls()) {
18728  // Don't bother with extra checks if we already know this one isn't visible.
18729  if (RD == D)
18730  continue;
18731 
18732  auto ND = cast<NamedDecl>(RD);
18733  if (LookupResult::isVisible(SemaRef, ND))
18734  return ND;
18735  }
18736 
18737  return nullptr;
18738 }
18739 
18740 static void
18742  SourceLocation Loc, QualType Ty,
18743  SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18744  // Find all of the associated namespaces and classes based on the
18745  // arguments we have.
18746  Sema::AssociatedNamespaceSet AssociatedNamespaces;
18747  Sema::AssociatedClassSet AssociatedClasses;
18748  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18749  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18750  AssociatedClasses);
18751 
18752  // C++ [basic.lookup.argdep]p3:
18753  // Let X be the lookup set produced by unqualified lookup (3.4.1)
18754  // and let Y be the lookup set produced by argument dependent
18755  // lookup (defined as follows). If X contains [...] then Y is
18756  // empty. Otherwise Y is the set of declarations found in the
18757  // namespaces associated with the argument types as described
18758  // below. The set of declarations found by the lookup of the name
18759  // is the union of X and Y.
18760  //
18761  // Here, we compute Y and add its members to the overloaded
18762  // candidate set.
18763  for (auto *NS : AssociatedNamespaces) {
18764  // When considering an associated namespace, the lookup is the
18765  // same as the lookup performed when the associated namespace is
18766  // used as a qualifier (3.4.3.2) except that:
18767  //
18768  // -- Any using-directives in the associated namespace are
18769  // ignored.
18770  //
18771  // -- Any namespace-scope friend functions declared in
18772  // associated classes are visible within their respective
18773  // namespaces even if they are not visible during an ordinary
18774  // lookup (11.4).
18775  DeclContext::lookup_result R = NS->lookup(Id.getName());
18776  for (auto *D : R) {
18777  auto *Underlying = D;
18778  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18779  Underlying = USD->getTargetDecl();
18780 
18781  if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18782  !isa<OMPDeclareMapperDecl>(Underlying))
18783  continue;
18784 
18785  if (!SemaRef.isVisible(D)) {
18786  D = findAcceptableDecl(SemaRef, D);
18787  if (!D)
18788  continue;
18789  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18790  Underlying = USD->getTargetDecl();
18791  }
18792  Lookups.emplace_back();
18793  Lookups.back().addDecl(Underlying);
18794  }
18795  }
18796 }
18797 
18798 static ExprResult
18800  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
18801  const DeclarationNameInfo &ReductionId, QualType Ty,
18802  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
18803  if (ReductionIdScopeSpec.isInvalid())
18804  return ExprError();
18805  SmallVector<UnresolvedSet<8>, 4> Lookups;
18806  if (S) {
18807  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18808  Lookup.suppressDiagnostics();
18809  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
18810  NamedDecl *D = Lookup.getRepresentativeDecl();
18811  do {
18812  S = S->getParent();
18813  } while (S && !S->isDeclScope(D));
18814  if (S)
18815  S = S->getParent();
18816  Lookups.emplace_back();
18817  Lookups.back().append(Lookup.begin(), Lookup.end());
18818  Lookup.clear();
18819  }
18820  } else if (auto *ULE =
18821  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18822  Lookups.push_back(UnresolvedSet<8>());
18823  Decl *PrevD = nullptr;
18824  for (NamedDecl *D : ULE->decls()) {
18825  if (D == PrevD)
18826  Lookups.push_back(UnresolvedSet<8>());
18827  else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18828  Lookups.back().addDecl(DRD);
18829  PrevD = D;
18830  }
18831  }
18832  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
18835  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18836  return !D->isInvalidDecl() &&
18837  (D->getType()->isDependentType() ||
18838  D->getType()->isInstantiationDependentType() ||
18839  D->getType()->containsUnexpandedParameterPack());
18840  })) {
18841  UnresolvedSet<8> ResSet;
18842  for (const UnresolvedSet<8> &Set : Lookups) {
18843  if (Set.empty())
18844  continue;
18845  ResSet.append(Set.begin(), Set.end());
18846  // The last item marks the end of all declarations at the specified scope.
18847  ResSet.addDecl(Set[Set.size() - 1]);
18848  }
18850  SemaRef.Context, /*NamingClass=*/nullptr,
18851  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
18852  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
18853  }
18854  // Lookup inside the classes.
18855  // C++ [over.match.oper]p3:
18856  // For a unary operator @ with an operand of a type whose
18857  // cv-unqualified version is T1, and for a binary operator @ with
18858  // a left operand of a type whose cv-unqualified version is T1 and
18859  // a right operand of a type whose cv-unqualified version is T2,
18860  // three sets of candidate functions, designated member
18861  // candidates, non-member candidates and built-in candidates, are
18862  // constructed as follows:
18863  // -- If T1 is a complete class type or a class currently being
18864  // defined, the set of member candidates is the result of the
18865  // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18866  // the set of member candidates is empty.
18867  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18868  Lookup.suppressDiagnostics();
18869  if (const auto *TyRec = Ty->getAs<RecordType>()) {
18870  // Complete the type if it can be completed.
18871  // If the type is neither complete nor being defined, bail out now.
18872  if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18873  TyRec->getDecl()->getDefinition()) {
18874  Lookup.clear();
18875  SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
18876  if (Lookup.empty()) {
18877  Lookups.emplace_back();
18878  Lookups.back().append(Lookup.begin(), Lookup.end());
18879  }
18880  }
18881  }
18882  // Perform ADL.
18883  if (SemaRef.getLangOpts().CPlusPlus)
18884  argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18885  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18886  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18887  if (!D->isInvalidDecl() &&
18888  SemaRef.Context.hasSameType(D->getType(), Ty))
18889  return D;
18890  return nullptr;
18891  }))
18892  return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18893  VK_LValue, Loc);
18894  if (SemaRef.getLangOpts().CPlusPlus) {
18895  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18896  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18897  if (!D->isInvalidDecl() &&
18898  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18899  !Ty.isMoreQualifiedThan(D->getType()))
18900  return D;
18901  return nullptr;
18902  })) {
18903  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18904  /*DetectVirtual=*/false);
18905  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18906  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18907  VD->getType().getUnqualifiedType()))) {
18908  if (SemaRef.CheckBaseClassAccess(
18909  Loc, VD->getType(), Ty, Paths.front(),
18910  /*DiagID=*/0) != Sema::AR_inaccessible) {
18911  SemaRef.BuildBasePathArray(Paths, BasePath);
18912  return SemaRef.BuildDeclRefExpr(
18913  VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18914  }
18915  }
18916  }
18917  }
18918  }
18919  if (ReductionIdScopeSpec.isSet()) {
18920  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18921  << Ty << Range;
18922  return ExprError();
18923  }
18924  return ExprEmpty();
18925 }
18926 
18927 namespace {
18928 /// Data for the reduction-based clauses.
18929 struct ReductionData {
18930  /// List of original reduction items.
18932  /// List of private copies of the reduction items.
18933  SmallVector<Expr *, 8> Privates;
18934  /// LHS expressions for the reduction_op expressions.
18936  /// RHS expressions for the reduction_op expressions.
18938  /// Reduction operation expression.
18939  SmallVector<Expr *, 8> ReductionOps;
18940  /// inscan copy operation expressions.
18941  SmallVector<Expr *, 8> InscanCopyOps;
18942  /// inscan copy temp array expressions for prefix sums.
18943  SmallVector<Expr *, 8> InscanCopyArrayTemps;
18944  /// inscan copy temp array element expressions for prefix sums.
18945  SmallVector<Expr *, 8> InscanCopyArrayElems;
18946  /// Taskgroup descriptors for the corresponding reduction items in
18947  /// in_reduction clauses.
18948  SmallVector<Expr *, 8> TaskgroupDescriptors;
18949  /// List of captures for clause.
18950  SmallVector<Decl *, 4> ExprCaptures;
18951  /// List of postupdate expressions.
18952  SmallVector<Expr *, 4> ExprPostUpdates;
18953  /// Reduction modifier.
18954  unsigned RedModifier = 0;
18955  ReductionData() = delete;
18956  /// Reserves required memory for the reduction data.
18957  ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18958  Vars.reserve(Size);
18959  Privates.reserve(Size);
18960  LHSs.reserve(Size);
18961  RHSs.reserve(Size);
18962  ReductionOps.reserve(Size);
18963  if (RedModifier == OMPC_REDUCTION_inscan) {
18964  InscanCopyOps.reserve(Size);
18965  InscanCopyArrayTemps.reserve(Size);
18966  InscanCopyArrayElems.reserve(Size);
18967  }
18968  TaskgroupDescriptors.reserve(Size);
18969  ExprCaptures.reserve(Size);
18970  ExprPostUpdates.reserve(Size);
18971  }
18972  /// Stores reduction item and reduction operation only (required for dependent
18973  /// reduction item).
18974  void push(Expr *Item, Expr *ReductionOp) {
18975  Vars.emplace_back(Item);
18976  Privates.emplace_back(nullptr);
18977  LHSs.emplace_back(nullptr);
18978  RHSs.emplace_back(nullptr);
18979  ReductionOps.emplace_back(ReductionOp);
18980  TaskgroupDescriptors.emplace_back(nullptr);
18981  if (RedModifier == OMPC_REDUCTION_inscan) {
18982  InscanCopyOps.push_back(nullptr);
18983  InscanCopyArrayTemps.push_back(nullptr);
18984  InscanCopyArrayElems.push_back(nullptr);
18985  }
18986  }
18987  /// Stores reduction data.
18988  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18989  Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18990  Expr *CopyArrayElem) {
18991  Vars.emplace_back(Item);
18992  Privates.emplace_back(Private);
18993  LHSs.emplace_back(LHS);
18994  RHSs.emplace_back(RHS);
18995  ReductionOps.emplace_back(ReductionOp);
18996  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18997  if (RedModifier == OMPC_REDUCTION_inscan) {
18998  InscanCopyOps.push_back(CopyOp);
18999  InscanCopyArrayTemps.push_back(CopyArrayTemp);
19000  InscanCopyArrayElems.push_back(CopyArrayElem);
19001  } else {
19002  assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19003  CopyArrayElem == nullptr &&
19004  "Copy operation must be used for inscan reductions only.");
19005  }
19006  }
19007 };
19008 } // namespace
19009 
19011  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19012  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19013  const Expr *Length = OASE->getLength();
19014  if (Length == nullptr) {
19015  // For array sections of the form [1:] or [:], we would need to analyze
19016  // the lower bound...
19017  if (OASE->getColonLocFirst().isValid())
19018  return false;
19019 
19020  // This is an array subscript which has implicit length 1!
19021  SingleElement = true;
19022  ArraySizes.push_back(llvm::APSInt::get(1));
19023  } else {
19024  Expr::EvalResult Result;
19025  if (!Length->EvaluateAsInt(Result, Context))
19026  return false;
19027 
19028  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19029  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19030  ArraySizes.push_back(ConstantLengthValue);
19031  }
19032 
19033  // Get the base of this array section and walk up from there.
19034  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19035 
19036  // We require length = 1 for all array sections except the right-most to
19037  // guarantee that the memory region is contiguous and has no holes in it.
19038  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19039  Length = TempOASE->getLength();
19040  if (Length == nullptr) {
19041  // For array sections of the form [1:] or [:], we would need to analyze
19042  // the lower bound...
19043  if (OASE->getColonLocFirst().isValid())
19044  return false;
19045 
19046  // This is an array subscript which has implicit length 1!
19047  ArraySizes.push_back(llvm::APSInt::get(1));
19048  } else {
19049  Expr::EvalResult Result;
19050  if (!Length->EvaluateAsInt(Result, Context))
19051  return false;
19052 
19053  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19054  if (ConstantLengthValue.getSExtValue() != 1)
19055  return false;
19056 
19057  ArraySizes.push_back(ConstantLengthValue);
19058  }
19059  Base = TempOASE->getBase()->IgnoreParenImpCasts();
19060  }
19061 
19062  // If we have a single element, we don't need to add the implicit lengths.
19063  if (!SingleElement) {
19064  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19065  // Has implicit length 1!
19066  ArraySizes.push_back(llvm::APSInt::get(1));
19067  Base = TempASE->getBase()->IgnoreParenImpCasts();
19068  }
19069  }
19070 
19071  // This array section can be privatized as a single value or as a constant
19072  // sized array.
19073  return true;
19074 }
19075 
19076 static BinaryOperatorKind
19078  if (BOK == BO_Add)
19079  return BO_AddAssign;
19080  if (BOK == BO_Mul)
19081  return BO_MulAssign;
19082  if (BOK == BO_And)
19083  return BO_AndAssign;
19084  if (BOK == BO_Or)
19085  return BO_OrAssign;
19086  if (BOK == BO_Xor)
19087  return BO_XorAssign;
19088  return BOK;
19089 }
19090 
19092  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19093  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19094  SourceLocation ColonLoc, SourceLocation EndLoc,
19095  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19096  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19097  DeclarationName DN = ReductionId.getName();
19099  BinaryOperatorKind BOK = BO_Comma;
19100 
19101  ASTContext &Context = S.Context;
19102  // OpenMP [2.14.3.6, reduction clause]
19103  // C
19104  // reduction-identifier is either an identifier or one of the following
19105  // operators: +, -, *, &, |, ^, && and ||
19106  // C++
19107  // reduction-identifier is either an id-expression or one of the following
19108  // operators: +, -, *, &, |, ^, && and ||
19109  switch (OOK) {
19110  case OO_Plus:
19111  case OO_Minus:
19112  BOK = BO_Add;
19113  break;
19114  case OO_Star:
19115  BOK = BO_Mul;
19116  break;
19117  case OO_Amp:
19118  BOK = BO_And;
19119  break;
19120  case OO_Pipe:
19121  BOK = BO_Or;
19122  break;
19123  case OO_Caret:
19124  BOK = BO_Xor;
19125  break;
19126  case OO_AmpAmp:
19127  BOK = BO_LAnd;
19128  break;
19129  case OO_PipePipe:
19130  BOK = BO_LOr;
19131  break;
19132  case OO_New:
19133  case OO_Delete:
19134  case OO_Array_New:
19135  case OO_Array_Delete:
19136  case OO_Slash:
19137  case OO_Percent:
19138  case OO_Tilde:
19139  case OO_Exclaim:
19140  case OO_Equal:
19141  case OO_Less:
19142  case OO_Greater:
19143  case OO_LessEqual:
19144  case OO_GreaterEqual:
19145  case OO_PlusEqual:
19146  case OO_MinusEqual:
19147  case OO_StarEqual:
19148  case OO_SlashEqual:
19149  case OO_PercentEqual:
19150  case OO_CaretEqual:
19151  case OO_AmpEqual:
19152  case OO_PipeEqual:
19153  case OO_LessLess:
19154  case OO_GreaterGreater:
19155  case OO_LessLessEqual:
19156  case OO_GreaterGreaterEqual:
19157  case OO_EqualEqual:
19158  case OO_ExclaimEqual:
19159  case OO_Spaceship:
19160  case OO_PlusPlus:
19161  case OO_MinusMinus:
19162  case OO_Comma:
19163  case OO_ArrowStar:
19164  case OO_Arrow:
19165  case OO_Call:
19166  case OO_Subscript:
19167  case OO_Conditional:
19168  case OO_Coawait:
19170  llvm_unreachable("Unexpected reduction identifier");
19171  case OO_None:
19172  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19173  if (II->isStr("max"))
19174  BOK = BO_GT;
19175  else if (II->isStr("min"))
19176  BOK = BO_LT;
19177  }
19178  break;
19179  }
19180  SourceRange ReductionIdRange;
19181  if (ReductionIdScopeSpec.isValid())
19182  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19183  else
19184  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19185  ReductionIdRange.setEnd(ReductionId.getEndLoc());
19186 
19187  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19188  bool FirstIter = true;
19189  for (Expr *RefExpr : VarList) {
19190  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19191  // OpenMP [2.1, C/C++]
19192  // A list item is a variable or array section, subject to the restrictions
19193  // specified in Section 2.4 on page 42 and in each of the sections
19194  // describing clauses and directives for which a list appears.
19195  // OpenMP [2.14.3.3, Restrictions, p.1]
19196  // A variable that is part of another variable (as an array or
19197  // structure element) cannot appear in a private clause.
19198  if (!FirstIter && IR != ER)
19199  ++IR;
19200  FirstIter = false;
19201  SourceLocation ELoc;
19202  SourceRange ERange;
19203  Expr *SimpleRefExpr = RefExpr;
19204  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19205  /*AllowArraySection=*/true);
19206  if (Res.second) {
19207  // Try to find 'declare reduction' corresponding construct before using
19208  // builtin/overloaded operators.
19209  QualType Type = Context.DependentTy;
19210  CXXCastPath BasePath;
19211  ExprResult DeclareReductionRef = buildDeclareReductionRef(
19212  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19213  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19214  Expr *ReductionOp = nullptr;
19215  if (S.CurContext->isDependentContext() &&
19216  (DeclareReductionRef.isUnset() ||
19217  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19218  ReductionOp = DeclareReductionRef.get();
19219  // It will be analyzed later.
19220  RD.push(RefExpr, ReductionOp);
19221  }
19222  ValueDecl *D = Res.first;
19223  if (!D)
19224  continue;
19225 
19226  Expr *TaskgroupDescriptor = nullptr;
19227  QualType Type;
19228  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19229  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19230  if (ASE) {
19231  Type = ASE->getType().getNonReferenceType();
19232  } else if (OASE) {
19233  QualType BaseType =
19235  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19236  Type = ATy->getElementType();
19237  else
19238  Type = BaseType->getPointeeType();
19239  Type = Type.getNonReferenceType();
19240  } else {
19242  }
19243  auto *VD = dyn_cast<VarDecl>(D);
19244 
19245  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19246  // A variable that appears in a private clause must not have an incomplete
19247  // type or a reference type.
19248  if (S.RequireCompleteType(ELoc, D->getType(),
19249  diag::err_omp_reduction_incomplete_type))
19250  continue;
19251  // OpenMP [2.14.3.6, reduction clause, Restrictions]
19252  // A list item that appears in a reduction clause must not be
19253  // const-qualified.
19254  if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19255  /*AcceptIfMutable*/ false, ASE || OASE))
19256  continue;
19257 
19258  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19259  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19260  // If a list-item is a reference type then it must bind to the same object
19261  // for all threads of the team.
19262  if (!ASE && !OASE) {
19263  if (VD) {
19264  VarDecl *VDDef = VD->getDefinition();
19265  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19266  DSARefChecker Check(Stack);
19267  if (Check.Visit(VDDef->getInit())) {
19268  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19269  << getOpenMPClauseName(ClauseKind) << ERange;
19270  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19271  continue;
19272  }
19273  }
19274  }
19275 
19276  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19277  // in a Construct]
19278  // Variables with the predetermined data-sharing attributes may not be
19279  // listed in data-sharing attributes clauses, except for the cases
19280  // listed below. For these exceptions only, listing a predetermined
19281  // variable in a data-sharing attribute clause is allowed and overrides
19282  // the variable's predetermined data-sharing attributes.
19283  // OpenMP [2.14.3.6, Restrictions, p.3]
19284  // Any number of reduction clauses can be specified on the directive,
19285  // but a list item can appear only once in the reduction clauses for that
19286  // directive.
19287  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19288  if (DVar.CKind == OMPC_reduction) {
19289  S.Diag(ELoc, diag::err_omp_once_referenced)
19290  << getOpenMPClauseName(ClauseKind);
19291  if (DVar.RefExpr)
19292  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19293  continue;
19294  }
19295  if (DVar.CKind != OMPC_unknown) {
19296  S.Diag(ELoc, diag::err_omp_wrong_dsa)
19297  << getOpenMPClauseName(DVar.CKind)
19298  << getOpenMPClauseName(OMPC_reduction);
19299  reportOriginalDsa(S, Stack, D, DVar);
19300  continue;
19301  }
19302 
19303  // OpenMP [2.14.3.6, Restrictions, p.1]
19304  // A list item that appears in a reduction clause of a worksharing
19305  // construct must be shared in the parallel regions to which any of the
19306  // worksharing regions arising from the worksharing construct bind.
19307  if (isOpenMPWorksharingDirective(CurrDir) &&
19308  !isOpenMPParallelDirective(CurrDir) &&
19309  !isOpenMPTeamsDirective(CurrDir)) {
19310  DVar = Stack->getImplicitDSA(D, true);
19311  if (DVar.CKind != OMPC_shared) {
19312  S.Diag(ELoc, diag::err_omp_required_access)
19313  << getOpenMPClauseName(OMPC_reduction)
19314  << getOpenMPClauseName(OMPC_shared);
19315  reportOriginalDsa(S, Stack, D, DVar);
19316  continue;
19317  }
19318  }
19319  } else {
19320  // Threadprivates cannot be shared between threads, so dignose if the base
19321  // is a threadprivate variable.
19322  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19323  if (DVar.CKind == OMPC_threadprivate) {
19324  S.Diag(ELoc, diag::err_omp_wrong_dsa)
19325  << getOpenMPClauseName(DVar.CKind)
19326  << getOpenMPClauseName(OMPC_reduction);
19327  reportOriginalDsa(S, Stack, D, DVar);
19328  continue;
19329  }
19330  }
19331 
19332  // Try to find 'declare reduction' corresponding construct before using
19333  // builtin/overloaded operators.
19334  CXXCastPath BasePath;
19335  ExprResult DeclareReductionRef = buildDeclareReductionRef(
19336  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19337  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19338  if (DeclareReductionRef.isInvalid())
19339  continue;
19340  if (S.CurContext->isDependentContext() &&
19341  (DeclareReductionRef.isUnset() ||
19342  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19343  RD.push(RefExpr, DeclareReductionRef.get());
19344  continue;
19345  }
19346  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19347  // Not allowed reduction identifier is found.
19348  S.Diag(ReductionId.getBeginLoc(),
19349  diag::err_omp_unknown_reduction_identifier)
19350  << Type << ReductionIdRange;
19351  continue;
19352  }
19353 
19354  // OpenMP [2.14.3.6, reduction clause, Restrictions]
19355  // The type of a list item that appears in a reduction clause must be valid
19356  // for the reduction-identifier. For a max or min reduction in C, the type
19357  // of the list item must be an allowed arithmetic data type: char, int,
19358  // float, double, or _Bool, possibly modified with long, short, signed, or
19359  // unsigned. For a max or min reduction in C++, the type of the list item
19360  // must be an allowed arithmetic data type: char, wchar_t, int, float,
19361  // double, or bool, possibly modified with long, short, signed, or unsigned.
19362  if (DeclareReductionRef.isUnset()) {
19363  if ((BOK == BO_GT || BOK == BO_LT) &&
19364  !(Type->isScalarType() ||
19365  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19366  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19367  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19368  if (!ASE && !OASE) {
19369  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19371  S.Diag(D->getLocation(),
19372  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19373  << D;
19374  }
19375  continue;
19376  }
19377  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19378  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19379  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19380  << getOpenMPClauseName(ClauseKind);
19381  if (!ASE && !OASE) {
19382  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19384  S.Diag(D->getLocation(),
19385  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19386  << D;
19387  }
19388  continue;
19389  }
19390  }
19391 
19392  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19393  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19394  D->hasAttrs() ? &D->getAttrs() : nullptr);
19395  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19396  D->hasAttrs() ? &D->getAttrs() : nullptr);
19397  QualType PrivateTy = Type;
19398 
19399  // Try if we can determine constant lengths for all array sections and avoid
19400  // the VLA.
19401  bool ConstantLengthOASE = false;
19402  if (OASE) {
19403  bool SingleElement;
19405  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19406  Context, OASE, SingleElement, ArraySizes);
19407 
19408  // If we don't have a single element, we must emit a constant array type.
19409  if (ConstantLengthOASE && !SingleElement) {
19410  for (llvm::APSInt &Size : ArraySizes)
19411  PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19413  /*IndexTypeQuals=*/0);
19414  }
19415  }
19416 
19417  if ((OASE && !ConstantLengthOASE) ||
19418  (!OASE && !ASE &&
19420  if (!Context.getTargetInfo().isVLASupported()) {
19421  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19422  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19423  S.Diag(ELoc, diag::note_vla_unsupported);
19424  continue;
19425  } else {
19426  S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19427  S.targetDiag(ELoc, diag::note_vla_unsupported);
19428  }
19429  }
19430  // For arrays/array sections only:
19431  // Create pseudo array type for private copy. The size for this array will
19432  // be generated during codegen.
19433  // For array subscripts or single variables Private Ty is the same as Type
19434  // (type of the variable or single array element).
19435  PrivateTy = Context.getVariableArrayType(
19436  Type,
19437  new (Context)
19438  OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19439  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
19440  } else if (!ASE && !OASE &&
19441  Context.getAsArrayType(D->getType().getNonReferenceType())) {
19442  PrivateTy = D->getType().getNonReferenceType();
19443  }
19444  // Private copy.
19445  VarDecl *PrivateVD =
19446  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19447  D->hasAttrs() ? &D->getAttrs() : nullptr,
19448  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19449  // Add initializer for private variable.
19450  Expr *Init = nullptr;
19451  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19452  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19453  if (DeclareReductionRef.isUsable()) {
19454  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19455  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19456  if (DRD->getInitializer()) {
19457  Init = DRDRef;
19458  RHSVD->setInit(DRDRef);
19460  }
19461  } else {
19462  switch (BOK) {
19463  case BO_Add:
19464  case BO_Xor:
19465  case BO_Or:
19466  case BO_LOr:
19467  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19468  if (Type->isScalarType() || Type->isAnyComplexType())
19469  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19470  break;
19471  case BO_Mul:
19472  case BO_LAnd:
19473  if (Type->isScalarType() || Type->isAnyComplexType()) {
19474  // '*' and '&&' reduction ops - initializer is '1'.
19475  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19476  }
19477  break;
19478  case BO_And: {
19479  // '&' reduction op - initializer is '~0'.
19480  QualType OrigType = Type;
19481  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19482  Type = ComplexTy->getElementType();
19483  if (Type->isRealFloatingType()) {
19484  llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19485  Context.getFloatTypeSemantics(Type));
19486  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19487  Type, ELoc);
19488  } else if (Type->isScalarType()) {
19489  uint64_t Size = Context.getTypeSize(Type);
19490  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19491  llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19492  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19493  }
19494  if (Init && OrigType->isAnyComplexType()) {
19495  // Init = 0xFFFF + 0xFFFFi;
19496  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19497  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19498  }
19499  Type = OrigType;
19500  break;
19501  }
19502  case BO_LT:
19503  case BO_GT: {
19504  // 'min' reduction op - initializer is 'Largest representable number in
19505  // the reduction list item type'.
19506  // 'max' reduction op - initializer is 'Least representable number in
19507  // the reduction list item type'.
19508  if (Type->isIntegerType() || Type->isPointerType()) {
19509  bool IsSigned = Type->hasSignedIntegerRepresentation();
19510  uint64_t Size = Context.getTypeSize(Type);
19511  QualType IntTy =
19512  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19513  llvm::APInt InitValue =
19514  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19515  : llvm::APInt::getMinValue(Size)
19516  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19517  : llvm::APInt::getMaxValue(Size);
19518  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19519  if (Type->isPointerType()) {
19520  // Cast to pointer type.
19522  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19523  if (CastExpr.isInvalid())
19524  continue;
19525  Init = CastExpr.get();
19526  }
19527  } else if (Type->isRealFloatingType()) {
19528  llvm::APFloat InitValue = llvm::APFloat::getLargest(
19529  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19530  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19531  Type, ELoc);
19532  }
19533  break;
19534  }
19535  case BO_PtrMemD:
19536  case BO_PtrMemI:
19537  case BO_MulAssign:
19538  case BO_Div:
19539  case BO_Rem:
19540  case BO_Sub:
19541  case BO_Shl:
19542  case BO_Shr:
19543  case BO_LE:
19544  case BO_GE:
19545  case BO_EQ:
19546  case BO_NE:
19547  case BO_Cmp:
19548  case BO_AndAssign:
19549  case BO_XorAssign:
19550  case BO_OrAssign:
19551  case BO_Assign:
19552  case BO_AddAssign:
19553  case BO_SubAssign:
19554  case BO_DivAssign:
19555  case BO_RemAssign:
19556  case BO_ShlAssign:
19557  case BO_ShrAssign:
19558  case BO_Comma:
19559  llvm_unreachable("Unexpected reduction operation");
19560  }
19561  }
19562  if (Init && DeclareReductionRef.isUnset()) {
19563  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19564  // Store initializer for single element in private copy. Will be used
19565  // during codegen.
19566  PrivateVD->setInit(RHSVD->getInit());
19567  PrivateVD->setInitStyle(RHSVD->getInitStyle());
19568  } else if (!Init) {
19569  S.ActOnUninitializedDecl(RHSVD);
19570  // Store initializer for single element in private copy. Will be used
19571  // during codegen.
19572  PrivateVD->setInit(RHSVD->getInit());
19573  PrivateVD->setInitStyle(RHSVD->getInitStyle());
19574  }
19575  if (RHSVD->isInvalidDecl())
19576  continue;
19577  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19578  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19579  << Type << ReductionIdRange;
19580  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19582  S.Diag(D->getLocation(),
19583  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19584  << D;
19585  continue;
19586  }
19587  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19588  ExprResult ReductionOp;
19589  if (DeclareReductionRef.isUsable()) {
19590  QualType RedTy = DeclareReductionRef.get()->getType();
19591  QualType PtrRedTy = Context.getPointerType(RedTy);
19592  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19593  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19594  if (!BasePath.empty()) {
19595  LHS = S.DefaultLvalueConversion(LHS.get());
19596  RHS = S.DefaultLvalueConversion(RHS.get());
19598  Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19599  LHS.get()->getValueKind(), FPOptionsOverride());
19601  Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19602  RHS.get()->getValueKind(), FPOptionsOverride());
19603  }
19605  QualType Params[] = {PtrRedTy, PtrRedTy};
19606  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19607  auto *OVE = new (Context) OpaqueValueExpr(
19608  ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19609  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19610  Expr *Args[] = {LHS.get(), RHS.get()};
19611  ReductionOp =
19612  CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19613  S.CurFPFeatureOverrides());
19614  } else {
19616  if (Type->isRecordType() && CombBOK != BOK) {
19618  ReductionOp =
19619  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19620  CombBOK, LHSDRE, RHSDRE);
19621  }
19622  if (!ReductionOp.isUsable()) {
19623  ReductionOp =
19624  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19625  LHSDRE, RHSDRE);
19626  if (ReductionOp.isUsable()) {
19627  if (BOK != BO_LT && BOK != BO_GT) {
19628  ReductionOp =
19629  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19630  BO_Assign, LHSDRE, ReductionOp.get());
19631  } else {
19632  auto *ConditionalOp = new (Context)
19633  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19634  RHSDRE, Type, VK_LValue, OK_Ordinary);
19635  ReductionOp =
19636  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19637  BO_Assign, LHSDRE, ConditionalOp);
19638  }
19639  }
19640  }
19641  if (ReductionOp.isUsable())
19642  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19643  /*DiscardedValue*/ false);
19644  if (!ReductionOp.isUsable())
19645  continue;
19646  }
19647 
19648  // Add copy operations for inscan reductions.
19649  // LHS = RHS;
19650  ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19651  if (ClauseKind == OMPC_reduction &&
19652  RD.RedModifier == OMPC_REDUCTION_inscan) {
19653  ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19654  CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19655  RHS.get());
19656  if (!CopyOpRes.isUsable())
19657  continue;
19658  CopyOpRes =
19659  S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19660  if (!CopyOpRes.isUsable())
19661  continue;
19662  // For simd directive and simd-based directives in simd mode no need to
19663  // construct temp array, need just a single temp element.
19664  if (Stack->getCurrentDirective() == OMPD_simd ||
19665  (S.getLangOpts().OpenMPSimd &&
19666  isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
19667  VarDecl *TempArrayVD =
19668  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19669  D->hasAttrs() ? &D->getAttrs() : nullptr);
19670  // Add a constructor to the temp decl.
19671  S.ActOnUninitializedDecl(TempArrayVD);
19672  TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19673  } else {
19674  // Build temp array for prefix sum.
19675  auto *Dim = new (S.Context)
19677  QualType ArrayTy =
19679  /*IndexTypeQuals=*/0, {ELoc, ELoc});
19680  VarDecl *TempArrayVD =
19681  buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19682  D->hasAttrs() ? &D->getAttrs() : nullptr);
19683  // Add a constructor to the temp decl.
19684  S.ActOnUninitializedDecl(TempArrayVD);
19685  TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19686  TempArrayElem =
19687  S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19688  auto *Idx = new (S.Context)
19690  TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19691  ELoc, Idx, ELoc);
19692  }
19693  }
19694 
19695  // OpenMP [2.15.4.6, Restrictions, p.2]
19696  // A list item that appears in an in_reduction clause of a task construct
19697  // must appear in a task_reduction clause of a construct associated with a
19698  // taskgroup region that includes the participating task in its taskgroup
19699  // set. The construct associated with the innermost region that meets this
19700  // condition must specify the same reduction-identifier as the in_reduction
19701  // clause.
19702  if (ClauseKind == OMPC_in_reduction) {
19703  SourceRange ParentSR;
19704  BinaryOperatorKind ParentBOK;
19705  const Expr *ParentReductionOp = nullptr;
19706  Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19707  DSAStackTy::DSAVarData ParentBOKDSA =
19708  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19709  ParentBOKTD);
19710  DSAStackTy::DSAVarData ParentReductionOpDSA =
19711  Stack->getTopMostTaskgroupReductionData(
19712  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19713  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19714  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19715  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
19716  (DeclareReductionRef.isUsable() && IsParentBOK) ||
19717  (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19718  bool EmitError = true;
19719  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
19720  llvm::FoldingSetNodeID RedId, ParentRedId;
19721  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19722  DeclareReductionRef.get()->Profile(RedId, Context,
19723  /*Canonical=*/true);
19724  EmitError = RedId != ParentRedId;
19725  }
19726  if (EmitError) {
19727  S.Diag(ReductionId.getBeginLoc(),
19728  diag::err_omp_reduction_identifier_mismatch)
19729  << ReductionIdRange << RefExpr->getSourceRange();
19730  S.Diag(ParentSR.getBegin(),
19731  diag::note_omp_previous_reduction_identifier)
19732  << ParentSR
19733  << (IsParentBOK ? ParentBOKDSA.RefExpr
19734  : ParentReductionOpDSA.RefExpr)
19735  ->getSourceRange();
19736  continue;
19737  }
19738  }
19739  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19740  }
19741 
19742  DeclRefExpr *Ref = nullptr;
19743  Expr *VarsExpr = RefExpr->IgnoreParens();
19744  if (!VD && !S.CurContext->isDependentContext()) {
19745  if (ASE || OASE) {
19746  TransformExprToCaptures RebuildToCapture(S, D);
19747  VarsExpr =
19748  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19749  Ref = RebuildToCapture.getCapturedExpr();
19750  } else {
19751  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
19752  }
19753  if (!S.isOpenMPCapturedDecl(D)) {
19754  RD.ExprCaptures.emplace_back(Ref->getDecl());
19755  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19756  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
19757  if (!RefRes.isUsable())
19758  continue;
19759  ExprResult PostUpdateRes =
19760  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19761  RefRes.get());
19762  if (!PostUpdateRes.isUsable())
19763  continue;
19764  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
19765  Stack->getCurrentDirective() == OMPD_taskgroup) {
19766  S.Diag(RefExpr->getExprLoc(),
19767  diag::err_omp_reduction_non_addressable_expression)
19768  << RefExpr->getSourceRange();
19769  continue;
19770  }
19771  RD.ExprPostUpdates.emplace_back(
19772  S.IgnoredValueConversions(PostUpdateRes.get()).get());
19773  }
19774  }
19775  }
19776  // All reduction items are still marked as reduction (to do not increase
19777  // code base size).
19778  unsigned Modifier = RD.RedModifier;
19779  // Consider task_reductions as reductions with task modifier. Required for
19780  // correct analysis of in_reduction clauses.
19781  if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19782  Modifier = OMPC_REDUCTION_task;
19783  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19784  ASE || OASE);
19785  if (Modifier == OMPC_REDUCTION_task &&
19786  (CurrDir == OMPD_taskgroup ||
19787  ((isOpenMPParallelDirective(CurrDir) ||
19788  isOpenMPWorksharingDirective(CurrDir)) &&
19789  !isOpenMPSimdDirective(CurrDir)))) {
19790  if (DeclareReductionRef.isUsable())
19791  Stack->addTaskgroupReductionData(D, ReductionIdRange,
19792  DeclareReductionRef.get());
19793  else
19794  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19795  }
19796  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
19797  TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19798  TempArrayElem.get());
19799  }
19800  return RD.Vars.empty();
19801 }
19802 
19805  SourceLocation StartLoc, SourceLocation LParenLoc,
19806  SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
19807  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19808  ArrayRef<Expr *> UnresolvedReductions) {
19809  if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
19810  Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19811  << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
19812  /*Last=*/OMPC_REDUCTION_unknown)
19813  << getOpenMPClauseName(OMPC_reduction);
19814  return nullptr;
19815  }
19816  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19817  // A reduction clause with the inscan reduction-modifier may only appear on a
19818  // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19819  // construct, a parallel worksharing-loop construct or a parallel
19820  // worksharing-loop SIMD construct.
19821  if (Modifier == OMPC_REDUCTION_inscan &&
19822  (DSAStack->getCurrentDirective() != OMPD_for &&
19823  DSAStack->getCurrentDirective() != OMPD_for_simd &&
19824  DSAStack->getCurrentDirective() != OMPD_simd &&
19825  DSAStack->getCurrentDirective() != OMPD_parallel_for &&
19826  DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
19827  Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19828  return nullptr;
19829  }
19830 
19831  ReductionData RD(VarList.size(), Modifier);
19832  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
19833  StartLoc, LParenLoc, ColonLoc, EndLoc,
19834  ReductionIdScopeSpec, ReductionId,
19835  UnresolvedReductions, RD))
19836  return nullptr;
19837 
19839  Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
19840  RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19841  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19842  RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19843  buildPreInits(Context, RD.ExprCaptures),
19844  buildPostUpdate(*this, RD.ExprPostUpdates));
19845 }
19846 
19848  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19849  SourceLocation ColonLoc, SourceLocation EndLoc,
19850  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19851  ArrayRef<Expr *> UnresolvedReductions) {
19852  ReductionData RD(VarList.size());
19853  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
19854  StartLoc, LParenLoc, ColonLoc, EndLoc,
19855  ReductionIdScopeSpec, ReductionId,
19856  UnresolvedReductions, RD))
19857  return nullptr;
19858 
19860  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19861  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19862  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19863  buildPreInits(Context, RD.ExprCaptures),
19864  buildPostUpdate(*this, RD.ExprPostUpdates));
19865 }
19866 
19868  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19869  SourceLocation ColonLoc, SourceLocation EndLoc,
19870  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19871  ArrayRef<Expr *> UnresolvedReductions) {
19872  ReductionData RD(VarList.size());
19873  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
19874  StartLoc, LParenLoc, ColonLoc, EndLoc,
19875  ReductionIdScopeSpec, ReductionId,
19876  UnresolvedReductions, RD))
19877  return nullptr;
19878 
19880  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19881  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19882  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19883  buildPreInits(Context, RD.ExprCaptures),
19884  buildPostUpdate(*this, RD.ExprPostUpdates));
19885 }
19886 
19888  SourceLocation LinLoc) {
19889  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19890  LinKind == OMPC_LINEAR_unknown) {
19891  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19892  return true;
19893  }
19894  return false;
19895 }
19896 
19899  bool IsDeclareSimd) {
19900  const auto *VD = dyn_cast_or_null<VarDecl>(D);
19901  // A variable must not have an incomplete type or a reference type.
19902  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19903  return true;
19904  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19905  !Type->isReferenceType()) {
19906  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19907  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19908  return true;
19909  }
19910  Type = Type.getNonReferenceType();
19911 
19912  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19913  // A variable that is privatized must not have a const-qualified type
19914  // unless it is of class type with a mutable member. This restriction does
19915  // not apply to the firstprivate clause, nor to the linear clause on
19916  // declarative directives (like declare simd).
19917  if (!IsDeclareSimd &&
19918  rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19919  return true;
19920 
19921  // A list item must be of integral or pointer type.
19922  Type = Type.getUnqualifiedType().getCanonicalType();
19923  const auto *Ty = Type.getTypePtrOrNull();
19924  if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19925  !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
19926  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19927  if (D) {
19928  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19930  Diag(D->getLocation(),
19931  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19932  << D;
19933  }
19934  return true;
19935  }
19936  return false;
19937 }
19938 
19940  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19941  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19942  SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19944  SmallVector<Expr *, 8> Privates;
19945  SmallVector<Expr *, 8> Inits;
19946  SmallVector<Decl *, 4> ExprCaptures;
19947  SmallVector<Expr *, 4> ExprPostUpdates;
19948  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19949  LinKind = OMPC_LINEAR_val;
19950  for (Expr *RefExpr : VarList) {
19951  assert(RefExpr && "NULL expr in OpenMP linear clause.");
19952  SourceLocation ELoc;
19953  SourceRange ERange;
19954  Expr *SimpleRefExpr = RefExpr;
19955  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19956  if (Res.second) {
19957  // It will be analyzed later.
19958  Vars.push_back(RefExpr);
19959  Privates.push_back(nullptr);
19960  Inits.push_back(nullptr);
19961  }
19962  ValueDecl *D = Res.first;
19963  if (!D)
19964  continue;
19965 
19966  QualType Type = D->getType();
19967  auto *VD = dyn_cast<VarDecl>(D);
19968 
19969  // OpenMP [2.14.3.7, linear clause]
19970  // A list-item cannot appear in more than one linear clause.
19971  // A list-item that appears in a linear clause cannot appear in any
19972  // other data-sharing attribute clause.
19973  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19974  if (DVar.RefExpr) {
19975  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19976  << getOpenMPClauseName(OMPC_linear);
19977  reportOriginalDsa(*this, DSAStack, D, DVar);
19978  continue;
19979  }
19980 
19981  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19982  continue;
19983  Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19984 
19985  // Build private copy of original var.
19986  VarDecl *Private =
19987  buildVarDecl(*this, ELoc, Type, D->getName(),
19988  D->hasAttrs() ? &D->getAttrs() : nullptr,
19989  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19990  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
19991  // Build var to save initial value.
19992  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
19993  Expr *InitExpr;
19994  DeclRefExpr *Ref = nullptr;
19995  if (!VD && !CurContext->isDependentContext()) {
19996  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19997  if (!isOpenMPCapturedDecl(D)) {
19998  ExprCaptures.push_back(Ref->getDecl());
19999  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20000  ExprResult RefRes = DefaultLvalueConversion(Ref);
20001  if (!RefRes.isUsable())
20002  continue;
20003  ExprResult PostUpdateRes =
20004  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20005  SimpleRefExpr, RefRes.get());
20006  if (!PostUpdateRes.isUsable())
20007  continue;
20008  ExprPostUpdates.push_back(
20009  IgnoredValueConversions(PostUpdateRes.get()).get());
20010  }
20011  }
20012  }
20013  if (LinKind == OMPC_LINEAR_uval)
20014  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20015  else
20016  InitExpr = VD ? SimpleRefExpr : Ref;
20017  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20018  /*DirectInit=*/false);
20019  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20020 
20021  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20022  Vars.push_back((VD || CurContext->isDependentContext())
20023  ? RefExpr->IgnoreParens()
20024  : Ref);
20025  Privates.push_back(PrivateRef);
20026  Inits.push_back(InitRef);
20027  }
20028 
20029  if (Vars.empty())
20030  return nullptr;
20031 
20032  Expr *StepExpr = Step;
20033  Expr *CalcStepExpr = nullptr;
20034  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
20035  !Step->isInstantiationDependent() &&
20037  SourceLocation StepLoc = Step->getBeginLoc();
20039  if (Val.isInvalid())
20040  return nullptr;
20041  StepExpr = Val.get();
20042 
20043  // Build var to save the step value.
20044  VarDecl *SaveVar =
20045  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20046  ExprResult SaveRef =
20047  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20048  ExprResult CalcStep =
20049  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20050  CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20051 
20052  // Warn about zero linear step (it would be probably better specified as
20053  // making corresponding variables 'const').
20054  if (std::optional<llvm::APSInt> Result =
20055  StepExpr->getIntegerConstantExpr(Context)) {
20056  if (!Result->isNegative() && !Result->isStrictlyPositive())
20057  Diag(StepLoc, diag::warn_omp_linear_step_zero)
20058  << Vars[0] << (Vars.size() > 1);
20059  } else if (CalcStep.isUsable()) {
20060  // Calculate the step beforehand instead of doing this on each iteration.
20061  // (This is not used if the number of iterations may be kfold-ed).
20062  CalcStepExpr = CalcStep.get();
20063  }
20064  }
20065 
20066  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20067  ColonLoc, EndLoc, Vars, Privates, Inits,
20068  StepExpr, CalcStepExpr,
20069  buildPreInits(Context, ExprCaptures),
20070  buildPostUpdate(*this, ExprPostUpdates));
20071 }
20072 
20074  Expr *NumIterations, Sema &SemaRef,
20075  Scope *S, DSAStackTy *Stack) {
20076  // Walk the vars and build update/final expressions for the CodeGen.
20077  SmallVector<Expr *, 8> Updates;
20078  SmallVector<Expr *, 8> Finals;
20079  SmallVector<Expr *, 8> UsedExprs;
20080  Expr *Step = Clause.getStep();
20081  Expr *CalcStep = Clause.getCalcStep();
20082  // OpenMP [2.14.3.7, linear clause]
20083  // If linear-step is not specified it is assumed to be 1.
20084  if (!Step)
20085  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20086  else if (CalcStep)
20087  Step = cast<BinaryOperator>(CalcStep)->getLHS();
20088  bool HasErrors = false;
20089  auto CurInit = Clause.inits().begin();
20090  auto CurPrivate = Clause.privates().begin();
20091  OpenMPLinearClauseKind LinKind = Clause.getModifier();
20092  for (Expr *RefExpr : Clause.varlists()) {
20093  SourceLocation ELoc;
20094  SourceRange ERange;
20095  Expr *SimpleRefExpr = RefExpr;
20096  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20097  ValueDecl *D = Res.first;
20098  if (Res.second || !D) {
20099  Updates.push_back(nullptr);
20100  Finals.push_back(nullptr);
20101  HasErrors = true;
20102  continue;
20103  }
20104  auto &&Info = Stack->isLoopControlVariable(D);
20105  // OpenMP [2.15.11, distribute simd Construct]
20106  // A list item may not appear in a linear clause, unless it is the loop
20107  // iteration variable.
20108  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20109  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20110  SemaRef.Diag(ELoc,
20111  diag::err_omp_linear_distribute_var_non_loop_iteration);
20112  Updates.push_back(nullptr);
20113  Finals.push_back(nullptr);
20114  HasErrors = true;
20115  continue;
20116  }
20117  Expr *InitExpr = *CurInit;
20118 
20119  // Build privatized reference to the current linear var.
20120  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20121  Expr *CapturedRef;
20122  if (LinKind == OMPC_LINEAR_uval)
20123  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20124  else
20125  CapturedRef =
20126  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20127  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20128  /*RefersToCapture=*/true);
20129 
20130  // Build update: Var = InitExpr + IV * Step
20132  if (!Info.first)
20134  SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20135  /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20136  else
20137  Update = *CurPrivate;
20138  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20139  /*DiscardedValue*/ false);
20140 
20141  // Build final: Var = PrivCopy;
20142  ExprResult Final;
20143  if (!Info.first)
20144  Final = SemaRef.BuildBinOp(
20145  S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20146  SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20147  else
20148  Final = *CurPrivate;
20149  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20150  /*DiscardedValue*/ false);
20151 
20152  if (!Update.isUsable() || !Final.isUsable()) {
20153  Updates.push_back(nullptr);
20154  Finals.push_back(nullptr);
20155  UsedExprs.push_back(nullptr);
20156  HasErrors = true;
20157  } else {
20158  Updates.push_back(Update.get());
20159  Finals.push_back(Final.get());
20160  if (!Info.first)
20161  UsedExprs.push_back(SimpleRefExpr);
20162  }
20163  ++CurInit;
20164  ++CurPrivate;
20165  }
20166  if (Expr *S = Clause.getStep())
20167  UsedExprs.push_back(S);
20168  // Fill the remaining part with the nullptr.
20169  UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20170  Clause.setUpdates(Updates);
20171  Clause.setFinals(Finals);
20172  Clause.setUsedExprs(UsedExprs);
20173  return HasErrors;
20174 }
20175 
20177  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20178  SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20180  for (Expr *RefExpr : VarList) {
20181  assert(RefExpr && "NULL expr in OpenMP linear clause.");
20182  SourceLocation ELoc;
20183  SourceRange ERange;
20184  Expr *SimpleRefExpr = RefExpr;
20185  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20186  if (Res.second) {
20187  // It will be analyzed later.
20188  Vars.push_back(RefExpr);
20189  }
20190  ValueDecl *D = Res.first;
20191  if (!D)
20192  continue;
20193 
20194  QualType QType = D->getType();
20195  auto *VD = dyn_cast<VarDecl>(D);
20196 
20197  // OpenMP [2.8.1, simd construct, Restrictions]
20198  // The type of list items appearing in the aligned clause must be
20199  // array, pointer, reference to array, or reference to pointer.
20201  const Type *Ty = QType.getTypePtrOrNull();
20202  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20203  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20204  << QType << getLangOpts().CPlusPlus << ERange;
20205  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20207  Diag(D->getLocation(),
20208  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20209  << D;
20210  continue;
20211  }
20212 
20213  // OpenMP [2.8.1, simd construct, Restrictions]
20214  // A list-item cannot appear in more than one aligned clause.
20215  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20216  Diag(ELoc, diag::err_omp_used_in_clause_twice)
20217  << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20218  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20219  << getOpenMPClauseName(OMPC_aligned);
20220  continue;
20221  }
20222 
20223  DeclRefExpr *Ref = nullptr;
20224  if (!VD && isOpenMPCapturedDecl(D))
20225  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20226  Vars.push_back(DefaultFunctionArrayConversion(
20227  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20228  .get());
20229  }
20230 
20231  // OpenMP [2.8.1, simd construct, Description]
20232  // The parameter of the aligned clause, alignment, must be a constant
20233  // positive integer expression.
20234  // If no optional parameter is specified, implementation-defined default
20235  // alignments for SIMD instructions on the target platforms are assumed.
20236  if (Alignment != nullptr) {
20237  ExprResult AlignResult =
20238  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20239  if (AlignResult.isInvalid())
20240  return nullptr;
20241  Alignment = AlignResult.get();
20242  }
20243  if (Vars.empty())
20244  return nullptr;
20245 
20246  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20247  EndLoc, Vars, Alignment);
20248 }
20249 
20251  SourceLocation StartLoc,
20252  SourceLocation LParenLoc,
20253  SourceLocation EndLoc) {
20255  SmallVector<Expr *, 8> SrcExprs;
20256  SmallVector<Expr *, 8> DstExprs;
20257  SmallVector<Expr *, 8> AssignmentOps;
20258  for (Expr *RefExpr : VarList) {
20259  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20260  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20261  // It will be analyzed later.
20262  Vars.push_back(RefExpr);
20263  SrcExprs.push_back(nullptr);
20264  DstExprs.push_back(nullptr);
20265  AssignmentOps.push_back(nullptr);
20266  continue;
20267  }
20268 
20269  SourceLocation ELoc = RefExpr->getExprLoc();
20270  // OpenMP [2.1, C/C++]
20271  // A list item is a variable name.
20272  // OpenMP [2.14.4.1, Restrictions, p.1]
20273  // A list item that appears in a copyin clause must be threadprivate.
20274  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20275  if (!DE || !isa<VarDecl>(DE->getDecl())) {
20276  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20277  << 0 << RefExpr->getSourceRange();
20278  continue;
20279  }
20280 
20281  Decl *D = DE->getDecl();
20282  auto *VD = cast<VarDecl>(D);
20283 
20284  QualType Type = VD->getType();
20286  // It will be analyzed later.
20287  Vars.push_back(DE);
20288  SrcExprs.push_back(nullptr);
20289  DstExprs.push_back(nullptr);
20290  AssignmentOps.push_back(nullptr);
20291  continue;
20292  }
20293 
20294  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20295  // A list item that appears in a copyin clause must be threadprivate.
20296  if (!DSAStack->isThreadPrivate(VD)) {
20297  Diag(ELoc, diag::err_omp_required_access)
20298  << getOpenMPClauseName(OMPC_copyin)
20299  << getOpenMPDirectiveName(OMPD_threadprivate);
20300  continue;
20301  }
20302 
20303  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20304  // A variable of class type (or array thereof) that appears in a
20305  // copyin clause requires an accessible, unambiguous copy assignment
20306  // operator for the class type.
20308  VarDecl *SrcVD =
20309  buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20310  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20311  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20312  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20313  VarDecl *DstVD =
20314  buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20315  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20316  DeclRefExpr *PseudoDstExpr =
20317  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20318  // For arrays generate assignment operation for single element and replace
20319  // it by the original array element in CodeGen.
20320  ExprResult AssignmentOp =
20321  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20322  PseudoSrcExpr);
20323  if (AssignmentOp.isInvalid())
20324  continue;
20325  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20326  /*DiscardedValue*/ false);
20327  if (AssignmentOp.isInvalid())
20328  continue;
20329 
20330  DSAStack->addDSA(VD, DE, OMPC_copyin);
20331  Vars.push_back(DE);
20332  SrcExprs.push_back(PseudoSrcExpr);
20333  DstExprs.push_back(PseudoDstExpr);
20334  AssignmentOps.push_back(AssignmentOp.get());
20335  }
20336 
20337  if (Vars.empty())
20338  return nullptr;
20339 
20340  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20341  SrcExprs, DstExprs, AssignmentOps);
20342 }
20343 
20345  SourceLocation StartLoc,
20346  SourceLocation LParenLoc,
20347  SourceLocation EndLoc) {
20349  SmallVector<Expr *, 8> SrcExprs;
20350  SmallVector<Expr *, 8> DstExprs;
20351  SmallVector<Expr *, 8> AssignmentOps;
20352  for (Expr *RefExpr : VarList) {
20353  assert(RefExpr && "NULL expr in OpenMP linear clause.");
20354  SourceLocation ELoc;
20355  SourceRange ERange;
20356  Expr *SimpleRefExpr = RefExpr;
20357  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20358  if (Res.second) {
20359  // It will be analyzed later.
20360  Vars.push_back(RefExpr);
20361  SrcExprs.push_back(nullptr);
20362  DstExprs.push_back(nullptr);
20363  AssignmentOps.push_back(nullptr);
20364  }
20365  ValueDecl *D = Res.first;
20366  if (!D)
20367  continue;
20368 
20369  QualType Type = D->getType();
20370  auto *VD = dyn_cast<VarDecl>(D);
20371 
20372  // OpenMP [2.14.4.2, Restrictions, p.2]
20373  // A list item that appears in a copyprivate clause may not appear in a
20374  // private or firstprivate clause on the single construct.
20375  if (!VD || !DSAStack->isThreadPrivate(VD)) {
20376  DSAStackTy::DSAVarData DVar =
20377  DSAStack->getTopDSA(D, /*FromParent=*/false);
20378  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20379  DVar.RefExpr) {
20380  Diag(ELoc, diag::err_omp_wrong_dsa)
20381  << getOpenMPClauseName(DVar.CKind)
20382  << getOpenMPClauseName(OMPC_copyprivate);
20383  reportOriginalDsa(*this, DSAStack, D, DVar);
20384  continue;
20385  }
20386 
20387  // OpenMP [2.11.4.2, Restrictions, p.1]
20388  // All list items that appear in a copyprivate clause must be either
20389  // threadprivate or private in the enclosing context.
20390  if (DVar.CKind == OMPC_unknown) {
20391  DVar = DSAStack->getImplicitDSA(D, false);
20392  if (DVar.CKind == OMPC_shared) {
20393  Diag(ELoc, diag::err_omp_required_access)
20394  << getOpenMPClauseName(OMPC_copyprivate)
20395  << "threadprivate or private in the enclosing context";
20396  reportOriginalDsa(*this, DSAStack, D, DVar);
20397  continue;
20398  }
20399  }
20400  }
20401 
20402  // Variably modified types are not supported.
20404  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20405  << getOpenMPClauseName(OMPC_copyprivate) << Type
20406  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20407  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20409  Diag(D->getLocation(),
20410  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20411  << D;
20412  continue;
20413  }
20414 
20415  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20416  // A variable of class type (or array thereof) that appears in a
20417  // copyin clause requires an accessible, unambiguous copy assignment
20418  // operator for the class type.
20419  Type = Context.getBaseElementType(Type.getNonReferenceType())
20420  .getUnqualifiedType();
20421  VarDecl *SrcVD =
20422  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20423  D->hasAttrs() ? &D->getAttrs() : nullptr);
20424  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20425  VarDecl *DstVD =
20426  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20427  D->hasAttrs() ? &D->getAttrs() : nullptr);
20428  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20429  ExprResult AssignmentOp = BuildBinOp(
20430  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20431  if (AssignmentOp.isInvalid())
20432  continue;
20433  AssignmentOp =
20434  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20435  if (AssignmentOp.isInvalid())
20436  continue;
20437 
20438  // No need to mark vars as copyprivate, they are already threadprivate or
20439  // implicitly private.
20440  assert(VD || isOpenMPCapturedDecl(D));
20441  Vars.push_back(
20442  VD ? RefExpr->IgnoreParens()
20443  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20444  SrcExprs.push_back(PseudoSrcExpr);
20445  DstExprs.push_back(PseudoDstExpr);
20446  AssignmentOps.push_back(AssignmentOp.get());
20447  }
20448 
20449  if (Vars.empty())
20450  return nullptr;
20451 
20452  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20453  Vars, SrcExprs, DstExprs, AssignmentOps);
20454 }
20455 
20457  SourceLocation StartLoc,
20458  SourceLocation LParenLoc,
20459  SourceLocation EndLoc) {
20460  if (VarList.empty())
20461  return nullptr;
20462 
20463  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20464 }
20465 
20466 /// Tries to find omp_depend_t. type.
20467 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20468  bool Diagnose = true) {
20469  QualType OMPDependT = Stack->getOMPDependT();
20470  if (!OMPDependT.isNull())
20471  return true;
20472  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20473  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20474  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20475  if (Diagnose)
20476  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20477  return false;
20478  }
20479  Stack->setOMPDependT(PT.get());
20480  return true;
20481 }
20482 
20484  SourceLocation LParenLoc,
20485  SourceLocation EndLoc) {
20486  if (!Depobj)
20487  return nullptr;
20488 
20489  bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20490 
20491  // OpenMP 5.0, 2.17.10.1 depobj Construct
20492  // depobj is an lvalue expression of type omp_depend_t.
20493  if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20494  !Depobj->isInstantiationDependent() &&
20495  !Depobj->containsUnexpandedParameterPack() &&
20496  (OMPDependTFound &&
20497  !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20498  /*CompareUnqualified=*/true))) {
20499  Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20500  << 0 << Depobj->getType() << Depobj->getSourceRange();
20501  }
20502 
20503  if (!Depobj->isLValue()) {
20504  Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20505  << 1 << Depobj->getSourceRange();
20506  }
20507 
20508  return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20509 }
20510 
20511 OMPClause *
20513  Expr *DepModifier, ArrayRef<Expr *> VarList,
20514  SourceLocation StartLoc, SourceLocation LParenLoc,
20515  SourceLocation EndLoc) {
20516  OpenMPDependClauseKind DepKind = Data.DepKind;
20517  SourceLocation DepLoc = Data.DepLoc;
20518  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20519  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20520  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20521  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20522  return nullptr;
20523  }
20524  if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20525  DepKind == OMPC_DEPEND_mutexinoutset) {
20526  Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20527  return nullptr;
20528  }
20529  if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20530  DSAStack->getCurrentDirective() == OMPD_depobj) &&
20531  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20532  DepKind == OMPC_DEPEND_sink ||
20533  ((LangOpts.OpenMP < 50 ||
20534  DSAStack->getCurrentDirective() == OMPD_depobj) &&
20535  DepKind == OMPC_DEPEND_depobj))) {
20536  SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20537  OMPC_DEPEND_outallmemory,
20538  OMPC_DEPEND_inoutallmemory};
20539  if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
20540  Except.push_back(OMPC_DEPEND_depobj);
20541  if (LangOpts.OpenMP < 51)
20542  Except.push_back(OMPC_DEPEND_inoutset);
20543  std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
20544  ? "depend modifier(iterator) or "
20545  : "";
20546  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20547  << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20548  /*Last=*/OMPC_DEPEND_unknown,
20549  Except)
20550  << getOpenMPClauseName(OMPC_depend);
20551  return nullptr;
20552  }
20553  if (DepModifier &&
20554  (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20555  Diag(DepModifier->getExprLoc(),
20556  diag::err_omp_depend_sink_source_with_modifier);
20557  return nullptr;
20558  }
20559  if (DepModifier &&
20560  !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
20561  Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20562 
20565  llvm::APSInt DepCounter(/*BitWidth=*/32);
20566  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20567  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20568  if (const Expr *OrderedCountExpr =
20569  DSAStack->getParentOrderedRegionParam().first) {
20570  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
20571  TotalDepCount.setIsUnsigned(/*Val=*/true);
20572  }
20573  }
20574  for (Expr *RefExpr : VarList) {
20575  assert(RefExpr && "NULL expr in OpenMP shared clause.");
20576  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20577  // It will be analyzed later.
20578  Vars.push_back(RefExpr);
20579  continue;
20580  }
20581 
20582  SourceLocation ELoc = RefExpr->getExprLoc();
20583  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20584  if (DepKind == OMPC_DEPEND_sink) {
20585  if (DSAStack->getParentOrderedRegionParam().first &&
20586  DepCounter >= TotalDepCount) {
20587  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20588  continue;
20589  }
20590  ++DepCounter;
20591  // OpenMP [2.13.9, Summary]
20592  // depend(dependence-type : vec), where dependence-type is:
20593  // 'sink' and where vec is the iteration vector, which has the form:
20594  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20595  // where n is the value specified by the ordered clause in the loop
20596  // directive, xi denotes the loop iteration variable of the i-th nested
20597  // loop associated with the loop directive, and di is a constant
20598  // non-negative integer.
20599  if (CurContext->isDependentContext()) {
20600  // It will be analyzed later.
20601  Vars.push_back(RefExpr);
20602  continue;
20603  }
20604  SimpleExpr = SimpleExpr->IgnoreImplicit();
20606  SourceLocation OOLoc;
20607  Expr *LHS = SimpleExpr;
20608  Expr *RHS = nullptr;
20609  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20610  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20611  OOLoc = BO->getOperatorLoc();
20612  LHS = BO->getLHS()->IgnoreParenImpCasts();
20613  RHS = BO->getRHS()->IgnoreParenImpCasts();
20614  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20615  OOK = OCE->getOperator();
20616  OOLoc = OCE->getOperatorLoc();
20617  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20618  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20619  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20620  OOK = MCE->getMethodDecl()
20621  ->getNameInfo()
20622  .getName()
20623  .getCXXOverloadedOperator();
20624  OOLoc = MCE->getCallee()->getExprLoc();
20625  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20626  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20627  }
20628  SourceLocation ELoc;
20629  SourceRange ERange;
20630  auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
20631  if (Res.second) {
20632  // It will be analyzed later.
20633  Vars.push_back(RefExpr);
20634  }
20635  ValueDecl *D = Res.first;
20636  if (!D)
20637  continue;
20638 
20639  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20640  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20641  continue;
20642  }
20643  if (RHS) {
20644  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
20645  RHS, OMPC_depend, /*StrictlyPositive=*/false);
20646  if (RHSRes.isInvalid())
20647  continue;
20648  }
20649  if (!CurContext->isDependentContext() &&
20650  DSAStack->getParentOrderedRegionParam().first &&
20651  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
20652  const ValueDecl *VD =
20653  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
20654  if (VD)
20655  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20656  << 1 << VD;
20657  else
20658  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
20659  continue;
20660  }
20661  OpsOffs.emplace_back(RHS, OOK);
20662  } else {
20663  bool OMPDependTFound = LangOpts.OpenMP >= 50;
20664  if (OMPDependTFound)
20665  OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
20666  DepKind == OMPC_DEPEND_depobj);
20667  if (DepKind == OMPC_DEPEND_depobj) {
20668  // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20669  // List items used in depend clauses with the depobj dependence type
20670  // must be expressions of the omp_depend_t type.
20671  if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20672  !RefExpr->isInstantiationDependent() &&
20673  !RefExpr->containsUnexpandedParameterPack() &&
20674  (OMPDependTFound &&
20675  !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
20676  RefExpr->getType()))) {
20677  Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20678  << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20679  continue;
20680  }
20681  if (!RefExpr->isLValue()) {
20682  Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20683  << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20684  continue;
20685  }
20686  } else {
20687  // OpenMP 5.0 [2.17.11, Restrictions]
20688  // List items used in depend clauses cannot be zero-length array
20689  // sections.
20690  QualType ExprTy = RefExpr->getType().getNonReferenceType();
20691  const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
20692  if (OASE) {
20693  QualType BaseType =
20695  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20696  ExprTy = ATy->getElementType();
20697  else
20698  ExprTy = BaseType->getPointeeType();
20699  ExprTy = ExprTy.getNonReferenceType();
20700  const Expr *Length = OASE->getLength();
20701  Expr::EvalResult Result;
20702  if (Length && !Length->isValueDependent() &&
20703  Length->EvaluateAsInt(Result, Context) &&
20704  Result.Val.getInt().isZero()) {
20705  Diag(ELoc,
20706  diag::err_omp_depend_zero_length_array_section_not_allowed)
20707  << SimpleExpr->getSourceRange();
20708  continue;
20709  }
20710  }
20711 
20712  // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20713  // List items used in depend clauses with the in, out, inout,
20714  // inoutset, or mutexinoutset dependence types cannot be
20715  // expressions of the omp_depend_t type.
20716  if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20717  !RefExpr->isInstantiationDependent() &&
20718  !RefExpr->containsUnexpandedParameterPack() &&
20719  (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20720  (OMPDependTFound &&
20721  DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
20722  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20723  << (LangOpts.OpenMP >= 50 ? 1 : 0)
20724  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20725  continue;
20726  }
20727 
20728  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20729  if (ASE && !ASE->getBase()->isTypeDependent() &&
20730  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
20731  !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20732  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20733  << (LangOpts.OpenMP >= 50 ? 1 : 0)
20734  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20735  continue;
20736  }
20737 
20738  ExprResult Res;
20739  {
20740  Sema::TentativeAnalysisScope Trap(*this);
20741  Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
20742  RefExpr->IgnoreParenImpCasts());
20743  }
20744  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20745  !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20746  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20747  << (LangOpts.OpenMP >= 50 ? 1 : 0)
20748  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20749  continue;
20750  }
20751  }
20752  }
20753  Vars.push_back(RefExpr->IgnoreParenImpCasts());
20754  }
20755 
20756  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
20757  TotalDepCount > VarList.size() &&
20758  DSAStack->getParentOrderedRegionParam().first &&
20759  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
20760  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20761  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
20762  }
20763  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20764  DepKind != OMPC_DEPEND_outallmemory &&
20765  DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20766  return nullptr;
20767 
20768  auto *C = OMPDependClause::Create(
20769  Context, StartLoc, LParenLoc, EndLoc,
20770  {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
20771  TotalDepCount.getZExtValue());
20772  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20773  DSAStack->isParentOrderedRegion())
20774  DSAStack->addDoacrossDependClause(C, OpsOffs);
20775  return C;
20776 }
20777 
20779  Expr *Device, SourceLocation StartLoc,
20780  SourceLocation LParenLoc,
20781  SourceLocation ModifierLoc,
20782  SourceLocation EndLoc) {
20783  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
20784  "Unexpected device modifier in OpenMP < 50.");
20785 
20786  bool ErrorFound = false;
20787  if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
20788  std::string Values =
20789  getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
20790  Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20791  << Values << getOpenMPClauseName(OMPC_device);
20792  ErrorFound = true;
20793  }
20794 
20795  Expr *ValExpr = Device;
20796  Stmt *HelperValStmt = nullptr;
20797 
20798  // OpenMP [2.9.1, Restrictions]
20799  // The device expression must evaluate to a non-negative integer value.
20800  ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
20801  /*StrictlyPositive=*/false) ||
20802  ErrorFound;
20803  if (ErrorFound)
20804  return nullptr;
20805 
20806  // OpenMP 5.0 [2.12.5, Restrictions]
20807  // In case of ancestor device-modifier, a requires directive with
20808  // the reverse_offload clause must be specified.
20809  if (Modifier == OMPC_DEVICE_ancestor) {
20810  if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
20811  targetDiag(
20812  StartLoc,
20813  diag::err_omp_device_ancestor_without_requires_reverse_offload);
20814  ErrorFound = true;
20815  }
20816  }
20817 
20818  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20819  OpenMPDirectiveKind CaptureRegion =
20820  getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
20821  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20822  ValExpr = MakeFullExpr(ValExpr).get();
20823  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20824  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20825  HelperValStmt = buildPreInits(Context, Captures);
20826  }
20827 
20828  return new (Context)
20829  OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20830  LParenLoc, ModifierLoc, EndLoc);
20831 }
20832 
20833 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
20834  DSAStackTy *Stack, QualType QTy,
20835  bool FullCheck = true) {
20836  if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
20837  return false;
20838  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
20839  !QTy.isTriviallyCopyableType(SemaRef.Context))
20840  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20841  return true;
20842 }
20843 
20844 /// Return true if it can be proven that the provided array expression
20845 /// (array section or array subscript) does NOT specify the whole size of the
20846 /// array whose base type is \a BaseQTy.
20848  const Expr *E,
20849  QualType BaseQTy) {
20850  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20851 
20852  // If this is an array subscript, it refers to the whole size if the size of
20853  // the dimension is constant and equals 1. Also, an array section assumes the
20854  // format of an array subscript if no colon is used.
20855  if (isa<ArraySubscriptExpr>(E) ||
20856  (OASE && OASE->getColonLocFirst().isInvalid())) {
20857  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20858  return ATy->getSize().getSExtValue() != 1;
20859  // Size can't be evaluated statically.
20860  return false;
20861  }
20862 
20863  assert(OASE && "Expecting array section if not an array subscript.");
20864  const Expr *LowerBound = OASE->getLowerBound();
20865  const Expr *Length = OASE->getLength();
20866 
20867  // If there is a lower bound that does not evaluates to zero, we are not
20868  // covering the whole dimension.
20869  if (LowerBound) {
20870  Expr::EvalResult Result;
20871  if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
20872  return false; // Can't get the integer value as a constant.
20873 
20874  llvm::APSInt ConstLowerBound = Result.Val.getInt();
20875  if (ConstLowerBound.getSExtValue())
20876  return true;
20877  }
20878 
20879  // If we don't have a length we covering the whole dimension.
20880  if (!Length)
20881  return false;
20882 
20883  // If the base is a pointer, we don't have a way to get the size of the
20884  // pointee.
20885  if (BaseQTy->isPointerType())
20886  return false;
20887 
20888  // We can only check if the length is the same as the size of the dimension
20889  // if we have a constant array.
20890  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20891  if (!CATy)
20892  return false;
20893 
20894  Expr::EvalResult Result;
20895  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20896  return false; // Can't get the integer value as a constant.
20897 
20898  llvm::APSInt ConstLength = Result.Val.getInt();
20899  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20900 }
20901 
20902 // Return true if it can be proven that the provided array expression (array
20903 // section or array subscript) does NOT specify a single element of the array
20904 // whose base type is \a BaseQTy.
20906  const Expr *E,
20907  QualType BaseQTy) {
20908  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20909 
20910  // An array subscript always refer to a single element. Also, an array section
20911  // assumes the format of an array subscript if no colon is used.
20912  if (isa<ArraySubscriptExpr>(E) ||
20913  (OASE && OASE->getColonLocFirst().isInvalid()))
20914  return false;
20915 
20916  assert(OASE && "Expecting array section if not an array subscript.");
20917  const Expr *Length = OASE->getLength();
20918 
20919  // If we don't have a length we have to check if the array has unitary size
20920  // for this dimension. Also, we should always expect a length if the base type
20921  // is pointer.
20922  if (!Length) {
20923  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20924  return ATy->getSize().getSExtValue() != 1;
20925  // We cannot assume anything.
20926  return false;
20927  }
20928 
20929  // Check if the length evaluates to 1.
20930  Expr::EvalResult Result;
20931  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20932  return false; // Can't get the integer value as a constant.
20933 
20934  llvm::APSInt ConstLength = Result.Val.getInt();
20935  return ConstLength.getSExtValue() != 1;
20936 }
20937 
20938 // The base of elements of list in a map clause have to be either:
20939 // - a reference to variable or field.
20940 // - a member expression.
20941 // - an array expression.
20942 //
20943 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20944 // reference to 'r'.
20945 //
20946 // If we have:
20947 //
20948 // struct SS {
20949 // Bla S;
20950 // foo() {
20951 // #pragma omp target map (S.Arr[:12]);
20952 // }
20953 // }
20954 //
20955 // We want to retrieve the member expression 'this->S';
20956 
20957 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20958 // If a list item is an array section, it must specify contiguous storage.
20959 //
20960 // For this restriction it is sufficient that we make sure only references
20961 // to variables or fields and array expressions, and that no array sections
20962 // exist except in the rightmost expression (unless they cover the whole
20963 // dimension of the array). E.g. these would be invalid:
20964 //
20965 // r.ArrS[3:5].Arr[6:7]
20966 //
20967 // r.ArrS[3:5].x
20968 //
20969 // but these would be valid:
20970 // r.ArrS[3].Arr[6:7]
20971 //
20972 // r.ArrS[3].x
20973 namespace {
20974 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20975  Sema &SemaRef;
20976  OpenMPClauseKind CKind = OMPC_unknown;
20977  OpenMPDirectiveKind DKind = OMPD_unknown;
20979  bool IsNonContiguous = false;
20980  bool NoDiagnose = false;
20981  const Expr *RelevantExpr = nullptr;
20982  bool AllowUnitySizeArraySection = true;
20983  bool AllowWholeSizeArraySection = true;
20984  bool AllowAnotherPtr = true;
20985  SourceLocation ELoc;
20986  SourceRange ERange;
20987 
20988  void emitErrorMsg() {
20989  // If nothing else worked, this is not a valid map clause expression.
20990  if (SemaRef.getLangOpts().OpenMP < 50) {
20991  SemaRef.Diag(ELoc,
20992  diag::err_omp_expected_named_var_member_or_array_expression)
20993  << ERange;
20994  } else {
20995  SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20996  << getOpenMPClauseName(CKind) << ERange;
20997  }
20998  }
20999 
21000 public:
21001  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21002  if (!isa<VarDecl>(DRE->getDecl())) {
21003  emitErrorMsg();
21004  return false;
21005  }
21006  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21007  RelevantExpr = DRE;
21008  // Record the component.
21009  Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21010  return true;
21011  }
21012 
21013  bool VisitMemberExpr(MemberExpr *ME) {
21014  Expr *E = ME;
21015  Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21016 
21017  if (isa<CXXThisExpr>(BaseE)) {
21018  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21019  // We found a base expression: this->Val.
21020  RelevantExpr = ME;
21021  } else {
21022  E = BaseE;
21023  }
21024 
21025  if (!isa<FieldDecl>(ME->getMemberDecl())) {
21026  if (!NoDiagnose) {
21027  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21028  << ME->getSourceRange();
21029  return false;
21030  }
21031  if (RelevantExpr)
21032  return false;
21033  return Visit(E);
21034  }
21035 
21036  auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21037 
21038  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21039  // A bit-field cannot appear in a map clause.
21040  //
21041  if (FD->isBitField()) {
21042  if (!NoDiagnose) {
21043  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21044  << ME->getSourceRange() << getOpenMPClauseName(CKind);
21045  return false;
21046  }
21047  if (RelevantExpr)
21048  return false;
21049  return Visit(E);
21050  }
21051 
21052  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21053  // If the type of a list item is a reference to a type T then the type
21054  // will be considered to be T for all purposes of this clause.
21055  QualType CurType = BaseE->getType().getNonReferenceType();
21056 
21057  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21058  // A list item cannot be a variable that is a member of a structure with
21059  // a union type.
21060  //
21061  if (CurType->isUnionType()) {
21062  if (!NoDiagnose) {
21063  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21064  << ME->getSourceRange();
21065  return false;
21066  }
21067  return RelevantExpr || Visit(E);
21068  }
21069 
21070  // If we got a member expression, we should not expect any array section
21071  // before that:
21072  //
21073  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21074  // If a list item is an element of a structure, only the rightmost symbol
21075  // of the variable reference can be an array section.
21076  //
21077  AllowUnitySizeArraySection = false;
21078  AllowWholeSizeArraySection = false;
21079 
21080  // Record the component.
21081  Components.emplace_back(ME, FD, IsNonContiguous);
21082  return RelevantExpr || Visit(E);
21083  }
21084 
21085  bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21086  Expr *E = AE->getBase()->IgnoreParenImpCasts();
21087 
21088  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
21089  if (!NoDiagnose) {
21090  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21091  << 0 << AE->getSourceRange();
21092  return false;
21093  }
21094  return RelevantExpr || Visit(E);
21095  }
21096 
21097  // If we got an array subscript that express the whole dimension we
21098  // can have any array expressions before. If it only expressing part of
21099  // the dimension, we can only have unitary-size array expressions.
21101  AllowWholeSizeArraySection = false;
21102 
21103  if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21104  Expr::EvalResult Result;
21105  if (!AE->getIdx()->isValueDependent() &&
21106  AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21107  !Result.Val.getInt().isZero()) {
21108  SemaRef.Diag(AE->getIdx()->getExprLoc(),
21109  diag::err_omp_invalid_map_this_expr);
21110  SemaRef.Diag(AE->getIdx()->getExprLoc(),
21111  diag::note_omp_invalid_subscript_on_this_ptr_map);
21112  }
21113  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21114  RelevantExpr = TE;
21115  }
21116 
21117  // Record the component - we don't have any declaration associated.
21118  Components.emplace_back(AE, nullptr, IsNonContiguous);
21119 
21120  return RelevantExpr || Visit(E);
21121  }
21122 
21123  bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21124  // After OMP 5.0 Array section in reduction clause will be implicitly
21125  // mapped
21126  assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21127  "Array sections cannot be implicitly mapped.");
21128  Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21129  QualType CurType =
21131 
21132  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21133  // If the type of a list item is a reference to a type T then the type
21134  // will be considered to be T for all purposes of this clause.
21135  if (CurType->isReferenceType())
21136  CurType = CurType->getPointeeType();
21137 
21138  bool IsPointer = CurType->isAnyPointerType();
21139 
21140  if (!IsPointer && !CurType->isArrayType()) {
21141  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21142  << 0 << OASE->getSourceRange();
21143  return false;
21144  }
21145 
21146  bool NotWhole =
21147  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21148  bool NotUnity =
21149  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21150 
21151  if (AllowWholeSizeArraySection) {
21152  // Any array section is currently allowed. Allowing a whole size array
21153  // section implies allowing a unity array section as well.
21154  //
21155  // If this array section refers to the whole dimension we can still
21156  // accept other array sections before this one, except if the base is a
21157  // pointer. Otherwise, only unitary sections are accepted.
21158  if (NotWhole || IsPointer)
21159  AllowWholeSizeArraySection = false;
21160  } else if (DKind == OMPD_target_update &&
21161  SemaRef.getLangOpts().OpenMP >= 50) {
21162  if (IsPointer && !AllowAnotherPtr)
21163  SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21164  << /*array of unknown bound */ 1;
21165  else
21166  IsNonContiguous = true;
21167  } else if (AllowUnitySizeArraySection && NotUnity) {
21168  // A unity or whole array section is not allowed and that is not
21169  // compatible with the properties of the current array section.
21170  if (NoDiagnose)
21171  return false;
21172  SemaRef.Diag(ELoc,
21173  diag::err_array_section_does_not_specify_contiguous_storage)
21174  << OASE->getSourceRange();
21175  return false;
21176  }
21177 
21178  if (IsPointer)
21179  AllowAnotherPtr = false;
21180 
21181  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21182  Expr::EvalResult ResultR;
21183  Expr::EvalResult ResultL;
21184  if (!OASE->getLength()->isValueDependent() &&
21185  OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21186  !ResultR.Val.getInt().isOne()) {
21187  SemaRef.Diag(OASE->getLength()->getExprLoc(),
21188  diag::err_omp_invalid_map_this_expr);
21189  SemaRef.Diag(OASE->getLength()->getExprLoc(),
21190  diag::note_omp_invalid_length_on_this_ptr_mapping);
21191  }
21192  if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21193  OASE->getLowerBound()->EvaluateAsInt(ResultL,
21194  SemaRef.getASTContext()) &&
21195  !ResultL.Val.getInt().isZero()) {
21196  SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21197  diag::err_omp_invalid_map_this_expr);
21198  SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21199  diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21200  }
21201  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21202  RelevantExpr = TE;
21203  }
21204 
21205  // Record the component - we don't have any declaration associated.
21206  Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21207  return RelevantExpr || Visit(E);
21208  }
21209  bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21210  Expr *Base = E->getBase();
21211 
21212  // Record the component - we don't have any declaration associated.
21213  Components.emplace_back(E, nullptr, IsNonContiguous);
21214 
21215  return Visit(Base->IgnoreParenImpCasts());
21216  }
21217 
21218  bool VisitUnaryOperator(UnaryOperator *UO) {
21219  if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21220  UO->getOpcode() != UO_Deref) {
21221  emitErrorMsg();
21222  return false;
21223  }
21224  if (!RelevantExpr) {
21225  // Record the component if haven't found base decl.
21226  Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21227  }
21228  return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21229  }
21230  bool VisitBinaryOperator(BinaryOperator *BO) {
21231  if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21232  emitErrorMsg();
21233  return false;
21234  }
21235 
21236  // Pointer arithmetic is the only thing we expect to happen here so after we
21237  // make sure the binary operator is a pointer type, the only thing we need
21238  // to do is to visit the subtree that has the same type as root (so that we
21239  // know the other subtree is just an offset)
21240  Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21241  Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21242  Components.emplace_back(BO, nullptr, false);
21243  assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21244  RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21245  "Either LHS or RHS have base decl inside");
21246  if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21247  return RelevantExpr || Visit(LE);
21248  return RelevantExpr || Visit(RE);
21249  }
21250  bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21251  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21252  RelevantExpr = CTE;
21253  Components.emplace_back(CTE, nullptr, IsNonContiguous);
21254  return true;
21255  }
21256  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21257  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21258  Components.emplace_back(COCE, nullptr, IsNonContiguous);
21259  return true;
21260  }
21261  bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21262  Expr *Source = E->getSourceExpr();
21263  if (!Source) {
21264  emitErrorMsg();
21265  return false;
21266  }
21267  return Visit(Source);
21268  }
21269  bool VisitStmt(Stmt *) {
21270  emitErrorMsg();
21271  return false;
21272  }
21273  const Expr *getFoundBase() const { return RelevantExpr; }
21274  explicit MapBaseChecker(
21275  Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21277  bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21278  : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21279  NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21280 };
21281 } // namespace
21282 
21283 /// Return the expression of the base of the mappable expression or null if it
21284 /// cannot be determined and do all the necessary checks to see if the
21285 /// expression is valid as a standalone mappable expression. In the process,
21286 /// record all the components of the expression.
21288  Sema &SemaRef, Expr *E,
21290  OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21291  SourceLocation ELoc = E->getExprLoc();
21292  SourceRange ERange = E->getSourceRange();
21293  MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21294  ERange);
21295  if (Checker.Visit(E->IgnoreParens())) {
21296  // Check if the highest dimension array section has length specified
21297  if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21298  (CKind == OMPC_to || CKind == OMPC_from)) {
21299  auto CI = CurComponents.rbegin();
21300  auto CE = CurComponents.rend();
21301  for (; CI != CE; ++CI) {
21302  const auto *OASE =
21303  dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21304  if (!OASE)
21305  continue;
21306  if (OASE && OASE->getLength())
21307  break;
21308  SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21309  << ERange;
21310  }
21311  }
21312  return Checker.getFoundBase();
21313  }
21314  return nullptr;
21315 }
21316 
21317 // Return true if expression E associated with value VD has conflicts with other
21318 // map information.
21319 static bool checkMapConflicts(
21320  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21321  bool CurrentRegionOnly,
21323  OpenMPClauseKind CKind) {
21324  assert(VD && E);
21325  SourceLocation ELoc = E->getExprLoc();
21326  SourceRange ERange = E->getSourceRange();
21327 
21328  // In order to easily check the conflicts we need to match each component of
21329  // the expression under test with the components of the expressions that are
21330  // already in the stack.
21331 
21332  assert(!CurComponents.empty() && "Map clause expression with no components!");
21333  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21334  "Map clause expression with unexpected base!");
21335 
21336  // Variables to help detecting enclosing problems in data environment nests.
21337  bool IsEnclosedByDataEnvironmentExpr = false;
21338  const Expr *EnclosingExpr = nullptr;
21339 
21340  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21341  VD, CurrentRegionOnly,
21342  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21343  ERange, CKind, &EnclosingExpr,
21345  StackComponents,
21347  if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21348  return false;
21349  assert(!StackComponents.empty() &&
21350  "Map clause expression with no components!");
21351  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21352  "Map clause expression with unexpected base!");
21353  (void)VD;
21354 
21355  // The whole expression in the stack.
21356  const Expr *RE = StackComponents.front().getAssociatedExpression();
21357 
21358  // Expressions must start from the same base. Here we detect at which
21359  // point both expressions diverge from each other and see if we can
21360  // detect if the memory referred to both expressions is contiguous and
21361  // do not overlap.
21362  auto CI = CurComponents.rbegin();
21363  auto CE = CurComponents.rend();
21364  auto SI = StackComponents.rbegin();
21365  auto SE = StackComponents.rend();
21366  for (; CI != CE && SI != SE; ++CI, ++SI) {
21367 
21368  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21369  // At most one list item can be an array item derived from a given
21370  // variable in map clauses of the same construct.
21371  if (CurrentRegionOnly &&
21372  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21373  isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21374  isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21375  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21376  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21377  isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21378  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21379  diag::err_omp_multiple_array_items_in_map_clause)
21380  << CI->getAssociatedExpression()->getSourceRange();
21381  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21382  diag::note_used_here)
21383  << SI->getAssociatedExpression()->getSourceRange();
21384  return true;
21385  }
21386 
21387  // Do both expressions have the same kind?
21388  if (CI->getAssociatedExpression()->getStmtClass() !=
21389  SI->getAssociatedExpression()->getStmtClass())
21390  break;
21391 
21392  // Are we dealing with different variables/fields?
21393  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21394  break;
21395  }
21396  // Check if the extra components of the expressions in the enclosing
21397  // data environment are redundant for the current base declaration.
21398  // If they are, the maps completely overlap, which is legal.
21399  for (; SI != SE; ++SI) {
21400  QualType Type;
21401  if (const auto *ASE =
21402  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21403  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21404  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21405  SI->getAssociatedExpression())) {
21406  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21407  Type =
21408  OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21409  } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21410  SI->getAssociatedExpression())) {
21411  Type = OASE->getBase()->getType()->getPointeeType();
21412  }
21413  if (Type.isNull() || Type->isAnyPointerType() ||
21415  SemaRef, SI->getAssociatedExpression(), Type))
21416  break;
21417  }
21418 
21419  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21420  // List items of map clauses in the same construct must not share
21421  // original storage.
21422  //
21423  // If the expressions are exactly the same or one is a subset of the
21424  // other, it means they are sharing storage.
21425  if (CI == CE && SI == SE) {
21426  if (CurrentRegionOnly) {
21427  if (CKind == OMPC_map) {
21428  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21429  } else {
21430  assert(CKind == OMPC_to || CKind == OMPC_from);
21431  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21432  << ERange;
21433  }
21434  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21435  << RE->getSourceRange();
21436  return true;
21437  }
21438  // If we find the same expression in the enclosing data environment,
21439  // that is legal.
21440  IsEnclosedByDataEnvironmentExpr = true;
21441  return false;
21442  }
21443 
21444  QualType DerivedType =
21445  std::prev(CI)->getAssociatedDeclaration()->getType();
21446  SourceLocation DerivedLoc =
21447  std::prev(CI)->getAssociatedExpression()->getExprLoc();
21448 
21449  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21450  // If the type of a list item is a reference to a type T then the type
21451  // will be considered to be T for all purposes of this clause.
21452  DerivedType = DerivedType.getNonReferenceType();
21453 
21454  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21455  // A variable for which the type is pointer and an array section
21456  // derived from that variable must not appear as list items of map
21457  // clauses of the same construct.
21458  //
21459  // Also, cover one of the cases in:
21460  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21461  // If any part of the original storage of a list item has corresponding
21462  // storage in the device data environment, all of the original storage
21463  // must have corresponding storage in the device data environment.
21464  //
21465  if (DerivedType->isAnyPointerType()) {
21466  if (CI == CE || SI == SE) {
21467  SemaRef.Diag(
21468  DerivedLoc,
21469  diag::err_omp_pointer_mapped_along_with_derived_section)
21470  << DerivedLoc;
21471  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21472  << RE->getSourceRange();
21473  return true;
21474  }
21475  if (CI->getAssociatedExpression()->getStmtClass() !=
21476  SI->getAssociatedExpression()->getStmtClass() ||
21477  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21478  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21479  assert(CI != CE && SI != SE);
21480  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21481  << DerivedLoc;
21482  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21483  << RE->getSourceRange();
21484  return true;
21485  }
21486  }
21487 
21488  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21489  // List items of map clauses in the same construct must not share
21490  // original storage.
21491  //
21492  // An expression is a subset of the other.
21493  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21494  if (CKind == OMPC_map) {
21495  if (CI != CE || SI != SE) {
21496  // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21497  // a pointer.
21498  auto Begin =
21499  CI != CE ? CurComponents.begin() : StackComponents.begin();
21500  auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21501  auto It = Begin;
21502  while (It != End && !It->getAssociatedDeclaration())
21503  std::advance(It, 1);
21504  assert(It != End &&
21505  "Expected at least one component with the declaration.");
21506  if (It != Begin && It->getAssociatedDeclaration()
21507  ->getType()
21508  .getCanonicalType()
21509  ->isAnyPointerType()) {
21510  IsEnclosedByDataEnvironmentExpr = false;
21511  EnclosingExpr = nullptr;
21512  return false;
21513  }
21514  }
21515  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21516  } else {
21517  assert(CKind == OMPC_to || CKind == OMPC_from);
21518  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21519  << ERange;
21520  }
21521  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21522  << RE->getSourceRange();
21523  return true;
21524  }
21525 
21526  // The current expression uses the same base as other expression in the
21527  // data environment but does not contain it completely.
21528  if (!CurrentRegionOnly && SI != SE)
21529  EnclosingExpr = RE;
21530 
21531  // The current expression is a subset of the expression in the data
21532  // environment.
21533  IsEnclosedByDataEnvironmentExpr |=
21534  (!CurrentRegionOnly && CI != CE && SI == SE);
21535 
21536  return false;
21537  });
21538 
21539  if (CurrentRegionOnly)
21540  return FoundError;
21541 
21542  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21543  // If any part of the original storage of a list item has corresponding
21544  // storage in the device data environment, all of the original storage must
21545  // have corresponding storage in the device data environment.
21546  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21547  // If a list item is an element of a structure, and a different element of
21548  // the structure has a corresponding list item in the device data environment
21549  // prior to a task encountering the construct associated with the map clause,
21550  // then the list item must also have a corresponding list item in the device
21551  // data environment prior to the task encountering the construct.
21552  //
21553  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21554  SemaRef.Diag(ELoc,
21555  diag::err_omp_original_storage_is_shared_and_does_not_contain)
21556  << ERange;
21557  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21558  << EnclosingExpr->getSourceRange();
21559  return true;
21560  }
21561 
21562  return FoundError;
21563 }
21564 
21565 // Look up the user-defined mapper given the mapper name and mapped type, and
21566 // build a reference to it.
21568  CXXScopeSpec &MapperIdScopeSpec,
21569  const DeclarationNameInfo &MapperId,
21570  QualType Type,
21571  Expr *UnresolvedMapper) {
21572  if (MapperIdScopeSpec.isInvalid())
21573  return ExprError();
21574  // Get the actual type for the array type.
21575  if (Type->isArrayType()) {
21576  assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21578  }
21579  // Find all user-defined mappers with the given MapperId.
21580  SmallVector<UnresolvedSet<8>, 4> Lookups;
21581  LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21582  Lookup.suppressDiagnostics();
21583  if (S) {
21584  while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21585  NamedDecl *D = Lookup.getRepresentativeDecl();
21586  while (S && !S->isDeclScope(D))
21587  S = S->getParent();
21588  if (S)
21589  S = S->getParent();
21590  Lookups.emplace_back();
21591  Lookups.back().append(Lookup.begin(), Lookup.end());
21592  Lookup.clear();
21593  }
21594  } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21595  // Extract the user-defined mappers with the given MapperId.
21596  Lookups.push_back(UnresolvedSet<8>());
21597  for (NamedDecl *D : ULE->decls()) {
21598  auto *DMD = cast<OMPDeclareMapperDecl>(D);
21599  assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21600  Lookups.back().addDecl(DMD);
21601  }
21602  }
21603  // Defer the lookup for dependent types. The results will be passed through
21604  // UnresolvedMapper on instantiation.
21605  if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21608  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21609  return !D->isInvalidDecl() &&
21610  (D->getType()->isDependentType() ||
21611  D->getType()->isInstantiationDependentType() ||
21612  D->getType()->containsUnexpandedParameterPack());
21613  })) {
21614  UnresolvedSet<8> URS;
21615  for (const UnresolvedSet<8> &Set : Lookups) {
21616  if (Set.empty())
21617  continue;
21618  URS.append(Set.begin(), Set.end());
21619  }
21621  SemaRef.Context, /*NamingClass=*/nullptr,
21622  MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21623  /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21624  }
21625  SourceLocation Loc = MapperId.getLoc();
21626  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21627  // The type must be of struct, union or class type in C and C++
21628  if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21629  (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21630  SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21631  return ExprError();
21632  }
21633  // Perform argument dependent lookup.
21634  if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21635  argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21636  // Return the first user-defined mapper with the desired type.
21637  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21638  Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21639  if (!D->isInvalidDecl() &&
21640  SemaRef.Context.hasSameType(D->getType(), Type))
21641  return D;
21642  return nullptr;
21643  }))
21644  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21645  // Find the first user-defined mapper with a type derived from the desired
21646  // type.
21647  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21648  Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21649  if (!D->isInvalidDecl() &&
21650  SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21651  !Type.isMoreQualifiedThan(D->getType()))
21652  return D;
21653  return nullptr;
21654  })) {
21655  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21656  /*DetectVirtual=*/false);
21657  if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21658  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21659  VD->getType().getUnqualifiedType()))) {
21660  if (SemaRef.CheckBaseClassAccess(
21661  Loc, VD->getType(), Type, Paths.front(),
21662  /*DiagID=*/0) != Sema::AR_inaccessible) {
21663  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21664  }
21665  }
21666  }
21667  }
21668  // Report error if a mapper is specified, but cannot be found.
21669  if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
21670  SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21671  << Type << MapperId.getName();
21672  return ExprError();
21673  }
21674  return ExprEmpty();
21675 }
21676 
21677 namespace {
21678 // Utility struct that gathers all the related lists associated with a mappable
21679 // expression.
21680 struct MappableVarListInfo {
21681  // The list of expressions.
21682  ArrayRef<Expr *> VarList;
21683  // The list of processed expressions.
21684  SmallVector<Expr *, 16> ProcessedVarList;
21685  // The mappble components for each expression.
21687  // The base declaration of the variable.
21688  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
21689  // The reference to the user-defined mapper associated with every expression.
21690  SmallVector<Expr *, 16> UDMapperList;
21691 
21692  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
21693  // We have a list of components and base declarations for each entry in the
21694  // variable list.
21695  VarComponents.reserve(VarList.size());
21696  VarBaseDeclarations.reserve(VarList.size());
21697  }
21698 };
21699 } // namespace
21700 
21701 // Check the validity of the provided variable list for the provided clause kind
21702 // \a CKind. In the check process the valid expressions, mappable expression
21703 // components, variables, and user-defined mappers are extracted and used to
21704 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21705 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21706 // and \a MapperId are expected to be valid if the clause kind is 'map'.
21708  Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
21709  MappableVarListInfo &MVLI, SourceLocation StartLoc,
21710  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
21711  ArrayRef<Expr *> UnresolvedMappers,
21713  ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
21714  bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
21715  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21716  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
21717  "Unexpected clause kind with mappable expressions!");
21718 
21719  // If the identifier of user-defined mapper is not specified, it is "default".
21720  // We do not change the actual name in this clause to distinguish whether a
21721  // mapper is specified explicitly, i.e., it is not explicitly specified when
21722  // MapperId.getName() is empty.
21723  if (!MapperId.getName() || MapperId.getName().isEmpty()) {
21724  auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
21725  MapperId.setName(DeclNames.getIdentifier(
21726  &SemaRef.getASTContext().Idents.get("default")));
21727  MapperId.setLoc(StartLoc);
21728  }
21729 
21730  // Iterators to find the current unresolved mapper expression.
21731  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21732  bool UpdateUMIt = false;
21733  Expr *UnresolvedMapper = nullptr;
21734 
21735  bool HasHoldModifier =
21736  llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21737 
21738  // Keep track of the mappable components and base declarations in this clause.
21739  // Each entry in the list is going to have a list of components associated. We
21740  // record each set of the components so that we can build the clause later on.
21741  // In the end we should have the same amount of declarations and component
21742  // lists.
21743 
21744  for (Expr *RE : MVLI.VarList) {
21745  assert(RE && "Null expr in omp to/from/map clause");
21746  SourceLocation ELoc = RE->getExprLoc();
21747 
21748  // Find the current unresolved mapper expression.
21749  if (UpdateUMIt && UMIt != UMEnd) {
21750  UMIt++;
21751  assert(
21752  UMIt != UMEnd &&
21753  "Expect the size of UnresolvedMappers to match with that of VarList");
21754  }
21755  UpdateUMIt = true;
21756  if (UMIt != UMEnd)
21757  UnresolvedMapper = *UMIt;
21758 
21759  const Expr *VE = RE->IgnoreParenLValueCasts();
21760 
21761  if (VE->isValueDependent() || VE->isTypeDependent() ||
21762  VE->isInstantiationDependent() ||
21764  // Try to find the associated user-defined mapper.
21766  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21767  VE->getType().getCanonicalType(), UnresolvedMapper);
21768  if (ER.isInvalid())
21769  continue;
21770  MVLI.UDMapperList.push_back(ER.get());
21771  // We can only analyze this information once the missing information is
21772  // resolved.
21773  MVLI.ProcessedVarList.push_back(RE);
21774  continue;
21775  }
21776 
21777  Expr *SimpleExpr = RE->IgnoreParenCasts();
21778 
21779  if (!RE->isLValue()) {
21780  if (SemaRef.getLangOpts().OpenMP < 50) {
21781  SemaRef.Diag(
21782  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21783  << RE->getSourceRange();
21784  } else {
21785  SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21786  << getOpenMPClauseName(CKind) << RE->getSourceRange();
21787  }
21788  continue;
21789  }
21790 
21792  ValueDecl *CurDeclaration = nullptr;
21793 
21794  // Obtain the array or member expression bases if required. Also, fill the
21795  // components array with all the components identified in the process.
21796  const Expr *BE =
21797  checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
21798  DSAS->getCurrentDirective(), NoDiagnose);
21799  if (!BE)
21800  continue;
21801 
21802  assert(!CurComponents.empty() &&
21803  "Invalid mappable expression information.");
21804 
21805  if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21806  // Add store "this" pointer to class in DSAStackTy for future checking
21807  DSAS->addMappedClassesQualTypes(TE->getType());
21808  // Try to find the associated user-defined mapper.
21810  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21811  VE->getType().getCanonicalType(), UnresolvedMapper);
21812  if (ER.isInvalid())
21813  continue;
21814  MVLI.UDMapperList.push_back(ER.get());
21815  // Skip restriction checking for variable or field declarations
21816  MVLI.ProcessedVarList.push_back(RE);
21817  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21818  MVLI.VarComponents.back().append(CurComponents.begin(),
21819  CurComponents.end());
21820  MVLI.VarBaseDeclarations.push_back(nullptr);
21821  continue;
21822  }
21823 
21824  // For the following checks, we rely on the base declaration which is
21825  // expected to be associated with the last component. The declaration is
21826  // expected to be a variable or a field (if 'this' is being mapped).
21827  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21828  assert(CurDeclaration && "Null decl on map clause.");
21829  assert(
21830  CurDeclaration->isCanonicalDecl() &&
21831  "Expecting components to have associated only canonical declarations.");
21832 
21833  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21834  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21835 
21836  assert((VD || FD) && "Only variables or fields are expected here!");
21837  (void)FD;
21838 
21839  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21840  // threadprivate variables cannot appear in a map clause.
21841  // OpenMP 4.5 [2.10.5, target update Construct]
21842  // threadprivate variables cannot appear in a from clause.
21843  if (VD && DSAS->isThreadPrivate(VD)) {
21844  if (NoDiagnose)
21845  continue;
21846  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21847  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21848  << getOpenMPClauseName(CKind);
21849  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
21850  continue;
21851  }
21852 
21853  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21854  // A list item cannot appear in both a map clause and a data-sharing
21855  // attribute clause on the same construct.
21856 
21857  // Check conflicts with other map clause expressions. We check the conflicts
21858  // with the current construct separately from the enclosing data
21859  // environment, because the restrictions are different. We only have to
21860  // check conflicts across regions for the map clauses.
21861  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21862  /*CurrentRegionOnly=*/true, CurComponents, CKind))
21863  break;
21864  if (CKind == OMPC_map &&
21865  (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
21866  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21867  /*CurrentRegionOnly=*/false, CurComponents, CKind))
21868  break;
21869 
21870  // OpenMP 4.5 [2.10.5, target update Construct]
21871  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21872  // If the type of a list item is a reference to a type T then the type will
21873  // be considered to be T for all purposes of this clause.
21874  auto I = llvm::find_if(
21875  CurComponents,
21877  return MC.getAssociatedDeclaration();
21878  });
21879  assert(I != CurComponents.end() && "Null decl on map clause.");
21880  (void)I;
21881  QualType Type;
21882  auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
21883  auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
21884  auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
21885  if (ASE) {
21886  Type = ASE->getType().getNonReferenceType();
21887  } else if (OASE) {
21888  QualType BaseType =
21890  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21891  Type = ATy->getElementType();
21892  else
21893  Type = BaseType->getPointeeType();
21894  Type = Type.getNonReferenceType();
21895  } else if (OAShE) {
21896  Type = OAShE->getBase()->getType()->getPointeeType();
21897  } else {
21898  Type = VE->getType();
21899  }
21900 
21901  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21902  // A list item in a to or from clause must have a mappable type.
21903  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21904  // A list item must have a mappable type.
21905  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21906  DSAS, Type, /*FullCheck=*/true))
21907  continue;
21908 
21909  if (CKind == OMPC_map) {
21910  // target enter data
21911  // OpenMP [2.10.2, Restrictions, p. 99]
21912  // A map-type must be specified in all map clauses and must be either
21913  // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
21914  // no map type is present.
21915  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21916  if (DKind == OMPD_target_enter_data &&
21917  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
21918  SemaRef.getLangOpts().OpenMP >= 52)) {
21919  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21920  << (IsMapTypeImplicit ? 1 : 0)
21921  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21922  << getOpenMPDirectiveName(DKind);
21923  continue;
21924  }
21925 
21926  // target exit_data
21927  // OpenMP [2.10.3, Restrictions, p. 102]
21928  // A map-type must be specified in all map clauses and must be either
21929  // from, release, or delete. Starting with OpenMP 5.2 the default map
21930  // type is `from` if no map type is present.
21931  if (DKind == OMPD_target_exit_data &&
21932  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21933  MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
21934  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21935  << (IsMapTypeImplicit ? 1 : 0)
21936  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21937  << getOpenMPDirectiveName(DKind);
21938  continue;
21939  }
21940 
21941  // The 'ompx_hold' modifier is specifically intended to be used on a
21942  // 'target' or 'target data' directive to prevent data from being unmapped
21943  // during the associated statement. It is not permitted on a 'target
21944  // enter data' or 'target exit data' directive, which have no associated
21945  // statement.
21946  if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21947  HasHoldModifier) {
21948  SemaRef.Diag(StartLoc,
21949  diag::err_omp_invalid_map_type_modifier_for_directive)
21950  << getOpenMPSimpleClauseTypeName(OMPC_map,
21951  OMPC_MAP_MODIFIER_ompx_hold)
21952  << getOpenMPDirectiveName(DKind);
21953  continue;
21954  }
21955 
21956  // target, target data
21957  // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21958  // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21959  // A map-type in a map clause must be to, from, tofrom or alloc
21960  if ((DKind == OMPD_target_data ||
21962  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21963  MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21964  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21965  << (IsMapTypeImplicit ? 1 : 0)
21966  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21967  << getOpenMPDirectiveName(DKind);
21968  continue;
21969  }
21970 
21971  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21972  // A list item cannot appear in both a map clause and a data-sharing
21973  // attribute clause on the same construct
21974  //
21975  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21976  // A list item cannot appear in both a map clause and a data-sharing
21977  // attribute clause on the same construct unless the construct is a
21978  // combined construct.
21979  if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21981  DKind == OMPD_target)) {
21982  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21983  if (isOpenMPPrivate(DVar.CKind)) {
21984  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21985  << getOpenMPClauseName(DVar.CKind)
21986  << getOpenMPClauseName(OMPC_map)
21987  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21988  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21989  continue;
21990  }
21991  }
21992  }
21993 
21994  // Try to find the associated user-defined mapper.
21996  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21997  Type.getCanonicalType(), UnresolvedMapper);
21998  if (ER.isInvalid())
21999  continue;
22000  MVLI.UDMapperList.push_back(ER.get());
22001 
22002  // Save the current expression.
22003  MVLI.ProcessedVarList.push_back(RE);
22004 
22005  // Store the components in the stack so that they can be used to check
22006  // against other clauses later on.
22007  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22008  /*WhereFoundClauseKind=*/OMPC_map);
22009 
22010  // Save the components and declaration to create the clause. For purposes of
22011  // the clause creation, any component list that has base 'this' uses
22012  // null as base declaration.
22013  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22014  MVLI.VarComponents.back().append(CurComponents.begin(),
22015  CurComponents.end());
22016  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
22017  : CurDeclaration);
22018  }
22019 }
22020 
22022  Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22023  ArrayRef<SourceLocation> MapTypeModifiersLoc,
22024  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22025  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22026  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22027  const OMPVarListLocTy &Locs, bool NoDiagnose,
22028  ArrayRef<Expr *> UnresolvedMappers) {
22029  OpenMPMapModifierKind Modifiers[] = {
22034 
22035  if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22036  BuiltinType::OMPIterator))
22037  Diag(IteratorModifier->getExprLoc(),
22038  diag::err_omp_map_modifier_not_iterator);
22039 
22040  // Process map-type-modifiers, flag errors for duplicate modifiers.
22041  unsigned Count = 0;
22042  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22043  if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22044  llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22045  Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22046  continue;
22047  }
22048  assert(Count < NumberOfOMPMapClauseModifiers &&
22049  "Modifiers exceed the allowed number of map type modifiers");
22050  Modifiers[Count] = MapTypeModifiers[I];
22051  ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22052  ++Count;
22053  }
22054 
22055  MappableVarListInfo MVLI(VarList);
22056  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22057  MapperIdScopeSpec, MapperId, UnresolvedMappers,
22058  MapType, Modifiers, IsMapTypeImplicit,
22059  NoDiagnose);
22060 
22061  // We need to produce a map clause even if we don't have variables so that
22062  // other diagnostics related with non-existing map clauses are accurate.
22063  return OMPMapClause::Create(
22064  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22065  MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22066  ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22067  MapType, IsMapTypeImplicit, MapLoc);
22068 }
22069 
22072  assert(ParsedType.isUsable());
22073 
22074  QualType ReductionType = GetTypeFromParser(ParsedType.get());
22075  if (ReductionType.isNull())
22076  return QualType();
22077 
22078  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22079  // A type name in a declare reduction directive cannot be a function type, an
22080  // array type, a reference type, or a type qualified with const, volatile or
22081  // restrict.
22082  if (ReductionType.hasQualifiers()) {
22083  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22084  return QualType();
22085  }
22086 
22087  if (ReductionType->isFunctionType()) {
22088  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22089  return QualType();
22090  }
22091  if (ReductionType->isReferenceType()) {
22092  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22093  return QualType();
22094  }
22095  if (ReductionType->isArrayType()) {
22096  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22097  return QualType();
22098  }
22099  return ReductionType;
22100 }
22101 
22103  Scope *S, DeclContext *DC, DeclarationName Name,
22104  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22105  AccessSpecifier AS, Decl *PrevDeclInScope) {
22106  SmallVector<Decl *, 8> Decls;
22107  Decls.reserve(ReductionTypes.size());
22108 
22109  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22111  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22112  // A reduction-identifier may not be re-declared in the current scope for the
22113  // same type or for a type that is compatible according to the base language
22114  // rules.
22115  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22116  OMPDeclareReductionDecl *PrevDRD = nullptr;
22117  bool InCompoundScope = true;
22118  if (S != nullptr) {
22119  // Find previous declaration with the same name not referenced in other
22120  // declarations.
22122  InCompoundScope =
22123  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22124  LookupName(Lookup, S);
22125  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22126  /*AllowInlineNamespace=*/false);
22127  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22129  while (Filter.hasNext()) {
22130  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22131  if (InCompoundScope) {
22132  auto I = UsedAsPrevious.find(PrevDecl);
22133  if (I == UsedAsPrevious.end())
22134  UsedAsPrevious[PrevDecl] = false;
22135  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22136  UsedAsPrevious[D] = true;
22137  }
22138  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22139  PrevDecl->getLocation();
22140  }
22141  Filter.done();
22142  if (InCompoundScope) {
22143  for (const auto &PrevData : UsedAsPrevious) {
22144  if (!PrevData.second) {
22145  PrevDRD = PrevData.first;
22146  break;
22147  }
22148  }
22149  }
22150  } else if (PrevDeclInScope != nullptr) {
22151  auto *PrevDRDInScope = PrevDRD =
22152  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22153  do {
22154  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22155  PrevDRDInScope->getLocation();
22156  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22157  } while (PrevDRDInScope != nullptr);
22158  }
22159  for (const auto &TyData : ReductionTypes) {
22160  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22161  bool Invalid = false;
22162  if (I != PreviousRedeclTypes.end()) {
22163  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22164  << TyData.first;
22165  Diag(I->second, diag::note_previous_definition);
22166  Invalid = true;
22167  }
22168  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22169  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22170  Name, TyData.first, PrevDRD);
22171  DC->addDecl(DRD);
22172  DRD->setAccess(AS);
22173  Decls.push_back(DRD);
22174  if (Invalid)
22175  DRD->setInvalidDecl();
22176  else
22177  PrevDRD = DRD;
22178  }
22179 
22180  return DeclGroupPtrTy::make(
22181  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22182 }
22183 
22185  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22186 
22187  // Enter new function scope.
22191 
22192  if (S != nullptr)
22193  PushDeclContext(S, DRD);
22194  else
22195  CurContext = DRD;
22196 
22199 
22200  QualType ReductionType = DRD->getType();
22201  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22202  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22203  // uses semantics of argument handles by value, but it should be passed by
22204  // reference. C lang does not support references, so pass all parameters as
22205  // pointers.
22206  // Create 'T omp_in;' variable.
22207  VarDecl *OmpInParm =
22208  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22209  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22210  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22211  // uses semantics of argument handles by value, but it should be passed by
22212  // reference. C lang does not support references, so pass all parameters as
22213  // pointers.
22214  // Create 'T omp_out;' variable.
22215  VarDecl *OmpOutParm =
22216  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22217  if (S != nullptr) {
22218  PushOnScopeChains(OmpInParm, S);
22219  PushOnScopeChains(OmpOutParm, S);
22220  } else {
22221  DRD->addDecl(OmpInParm);
22222  DRD->addDecl(OmpOutParm);
22223  }
22224  Expr *InE =
22225  ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22226  Expr *OutE =
22227  ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22228  DRD->setCombinerData(InE, OutE);
22229 }
22230 
22232  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22235 
22236  PopDeclContext();
22238 
22239  if (Combiner != nullptr)
22240  DRD->setCombiner(Combiner);
22241  else
22242  DRD->setInvalidDecl();
22243 }
22244 
22246  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22247 
22248  // Enter new function scope.
22251 
22252  if (S != nullptr)
22253  PushDeclContext(S, DRD);
22254  else
22255  CurContext = DRD;
22256 
22259 
22260  QualType ReductionType = DRD->getType();
22261  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22262  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22263  // uses semantics of argument handles by value, but it should be passed by
22264  // reference. C lang does not support references, so pass all parameters as
22265  // pointers.
22266  // Create 'T omp_priv;' variable.
22267  VarDecl *OmpPrivParm =
22268  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22269  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22270  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22271  // uses semantics of argument handles by value, but it should be passed by
22272  // reference. C lang does not support references, so pass all parameters as
22273  // pointers.
22274  // Create 'T omp_orig;' variable.
22275  VarDecl *OmpOrigParm =
22276  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22277  if (S != nullptr) {
22278  PushOnScopeChains(OmpPrivParm, S);
22279  PushOnScopeChains(OmpOrigParm, S);
22280  } else {
22281  DRD->addDecl(OmpPrivParm);
22282  DRD->addDecl(OmpOrigParm);
22283  }
22284  Expr *OrigE =
22285  ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22286  Expr *PrivE =
22287  ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22288  DRD->setInitializerData(OrigE, PrivE);
22289  return OmpPrivParm;
22290 }
22291 
22293  VarDecl *OmpPrivParm) {
22294  auto *DRD = cast<OMPDeclareReductionDecl>(D);
22297 
22298  PopDeclContext();
22300 
22301  if (Initializer != nullptr) {
22302  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
22303  } else if (OmpPrivParm->hasInit()) {
22304  DRD->setInitializer(OmpPrivParm->getInit(),
22305  OmpPrivParm->isDirectInit()
22308  } else {
22309  DRD->setInvalidDecl();
22310  }
22311 }
22312 
22314  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22315  for (Decl *D : DeclReductions.get()) {
22316  if (IsValid) {
22317  if (S)
22318  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22319  /*AddToContext=*/false);
22320  } else {
22321  D->setInvalidDecl();
22322  }
22323  }
22324  return DeclReductions;
22325 }
22326 
22328  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22329  QualType T = TInfo->getType();
22330  if (D.isInvalidType())
22331  return true;
22332 
22333  if (getLangOpts().CPlusPlus) {
22334  // Check that there are no default arguments (C++ only).
22336  }
22337 
22338  return CreateParsedType(T, TInfo);
22339 }
22340 
22343  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22344 
22345  QualType MapperType = GetTypeFromParser(ParsedType.get());
22346  assert(!MapperType.isNull() && "Expect valid mapper type");
22347 
22348  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22349  // The type must be of struct, union or class type in C and C++
22350  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22351  Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22352  return QualType();
22353  }
22354  return MapperType;
22355 }
22356 
22358  Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22360  Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22361  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22363  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22364  // A mapper-identifier may not be redeclared in the current scope for the
22365  // same type or for a type that is compatible according to the base language
22366  // rules.
22367  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22368  OMPDeclareMapperDecl *PrevDMD = nullptr;
22369  bool InCompoundScope = true;
22370  if (S != nullptr) {
22371  // Find previous declaration with the same name not referenced in other
22372  // declarations.
22374  InCompoundScope =
22375  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22376  LookupName(Lookup, S);
22377  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22378  /*AllowInlineNamespace=*/false);
22379  llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22381  while (Filter.hasNext()) {
22382  auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22383  if (InCompoundScope) {
22384  auto I = UsedAsPrevious.find(PrevDecl);
22385  if (I == UsedAsPrevious.end())
22386  UsedAsPrevious[PrevDecl] = false;
22387  if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22388  UsedAsPrevious[D] = true;
22389  }
22390  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22391  PrevDecl->getLocation();
22392  }
22393  Filter.done();
22394  if (InCompoundScope) {
22395  for (const auto &PrevData : UsedAsPrevious) {
22396  if (!PrevData.second) {
22397  PrevDMD = PrevData.first;
22398  break;
22399  }
22400  }
22401  }
22402  } else if (PrevDeclInScope) {
22403  auto *PrevDMDInScope = PrevDMD =
22404  cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22405  do {
22406  PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22407  PrevDMDInScope->getLocation();
22408  PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22409  } while (PrevDMDInScope != nullptr);
22410  }
22411  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22412  bool Invalid = false;
22413  if (I != PreviousRedeclTypes.end()) {
22414  Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22415  << MapperType << Name;
22416  Diag(I->second, diag::note_previous_definition);
22417  Invalid = true;
22418  }
22419  // Build expressions for implicit maps of data members with 'default'
22420  // mappers.
22421  SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22422  Clauses.end());
22423  if (LangOpts.OpenMP >= 50)
22424  processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22425  auto *DMD =
22426  OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22427  ClausesWithImplicit, PrevDMD);
22428  if (S)
22429  PushOnScopeChains(DMD, S);
22430  else
22431  DC->addDecl(DMD);
22432  DMD->setAccess(AS);
22433  if (Invalid)
22434  DMD->setInvalidDecl();
22435 
22436  auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22437  VD->setDeclContext(DMD);
22438  VD->setLexicalDeclContext(DMD);
22439  DMD->addDecl(VD);
22440  DMD->setMapperVarRef(MapperVarRef);
22441 
22442  return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22443 }
22444 
22445 ExprResult
22447  SourceLocation StartLoc,
22448  DeclarationName VN) {
22449  TypeSourceInfo *TInfo =
22450  Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22452  StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22453  MapperType, TInfo, SC_None);
22454  if (S)
22455  PushOnScopeChains(VD, S, /*AddToContext=*/false);
22456  Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22457  DSAStack->addDeclareMapperVarRef(E);
22458  return E;
22459 }
22460 
22462  if (DSAStack->getDeclareMapperVarRef())
22463  DSAStack->addIteratorVarDecl(VD);
22464 }
22465 
22467  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22468  const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22469  if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22470  if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22471  return true;
22473  return true;
22474  if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22475  return true;
22476  return false;
22477  }
22478  return true;
22479 }
22480 
22482  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22483  return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22484 }
22485 
22487  SourceLocation StartLoc,
22488  SourceLocation LParenLoc,
22489  SourceLocation EndLoc) {
22490  Expr *ValExpr = NumTeams;
22491  Stmt *HelperValStmt = nullptr;
22492 
22493  // OpenMP [teams Constrcut, Restrictions]
22494  // The num_teams expression must evaluate to a positive integer value.
22495  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22496  /*StrictlyPositive=*/true))
22497  return nullptr;
22498 
22499  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22500  OpenMPDirectiveKind CaptureRegion =
22501  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22502  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22503  ValExpr = MakeFullExpr(ValExpr).get();
22504  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22505  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22506  HelperValStmt = buildPreInits(Context, Captures);
22507  }
22508 
22509  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22510  StartLoc, LParenLoc, EndLoc);
22511 }
22512 
22514  SourceLocation StartLoc,
22515  SourceLocation LParenLoc,
22516  SourceLocation EndLoc) {
22517  Expr *ValExpr = ThreadLimit;
22518  Stmt *HelperValStmt = nullptr;
22519 
22520  // OpenMP [teams Constrcut, Restrictions]
22521  // The thread_limit expression must evaluate to a positive integer value.
22522  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22523  /*StrictlyPositive=*/true))
22524  return nullptr;
22525 
22526  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22528  DKind, OMPC_thread_limit, LangOpts.OpenMP);
22529  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22530  ValExpr = MakeFullExpr(ValExpr).get();
22531  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22532  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22533  HelperValStmt = buildPreInits(Context, Captures);
22534  }
22535 
22536  return new (Context) OMPThreadLimitClause(
22537  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22538 }
22539 
22541  SourceLocation StartLoc,
22542  SourceLocation LParenLoc,
22543  SourceLocation EndLoc) {
22544  Expr *ValExpr = Priority;
22545  Stmt *HelperValStmt = nullptr;
22546  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22547 
22548  // OpenMP [2.9.1, task Constrcut]
22549  // The priority-value is a non-negative numerical scalar expression.
22551  ValExpr, *this, OMPC_priority,
22552  /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22553  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22554  return nullptr;
22555 
22556  return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22557  StartLoc, LParenLoc, EndLoc);
22558 }
22559 
22561  OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22562  SourceLocation StartLoc, SourceLocation LParenLoc,
22563  SourceLocation ModifierLoc, SourceLocation EndLoc) {
22564  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22565  "Unexpected grainsize modifier in OpenMP < 51.");
22566 
22567  if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22568  std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22570  Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22571  << Values << getOpenMPClauseName(OMPC_grainsize);
22572  return nullptr;
22573  }
22574 
22575  Expr *ValExpr = Grainsize;
22576  Stmt *HelperValStmt = nullptr;
22577  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22578 
22579  // OpenMP [2.9.2, taskloop Constrcut]
22580  // The parameter of the grainsize clause must be a positive integer
22581  // expression.
22582  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22583  /*StrictlyPositive=*/true,
22584  /*BuildCapture=*/true,
22585  DSAStack->getCurrentDirective(),
22586  &CaptureRegion, &HelperValStmt))
22587  return nullptr;
22588 
22589  return new (Context)
22590  OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22591  StartLoc, LParenLoc, ModifierLoc, EndLoc);
22592 }
22593 
22595  OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22596  SourceLocation StartLoc, SourceLocation LParenLoc,
22597  SourceLocation ModifierLoc, SourceLocation EndLoc) {
22598  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22599  "Unexpected num_tasks modifier in OpenMP < 51.");
22600 
22601  if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22602  std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22604  Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22605  << Values << getOpenMPClauseName(OMPC_num_tasks);
22606  return nullptr;
22607  }
22608 
22609  Expr *ValExpr = NumTasks;
22610  Stmt *HelperValStmt = nullptr;
22611  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22612 
22613  // OpenMP [2.9.2, taskloop Constrcut]
22614  // The parameter of the num_tasks clause must be a positive integer
22615  // expression.
22617  ValExpr, *this, OMPC_num_tasks,
22618  /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22619  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22620  return nullptr;
22621 
22622  return new (Context)
22623  OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22624  StartLoc, LParenLoc, ModifierLoc, EndLoc);
22625 }
22626 
22628  SourceLocation LParenLoc,
22629  SourceLocation EndLoc) {
22630  // OpenMP [2.13.2, critical construct, Description]
22631  // ... where hint-expression is an integer constant expression that evaluates
22632  // to a valid lock hint.
22633  ExprResult HintExpr =
22634  VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22635  if (HintExpr.isInvalid())
22636  return nullptr;
22637  return new (Context)
22638  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22639 }
22640 
22641 /// Tries to find omp_event_handle_t type.
22643  DSAStackTy *Stack) {
22644  QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22645  if (!OMPEventHandleT.isNull())
22646  return true;
22647  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22648  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22649  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22650  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22651  return false;
22652  }
22653  Stack->setOMPEventHandleT(PT.get());
22654  return true;
22655 }
22656 
22658  SourceLocation LParenLoc,
22659  SourceLocation EndLoc) {
22660  if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
22661  !Evt->isInstantiationDependent() &&
22663  if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
22664  return nullptr;
22665  // OpenMP 5.0, 2.10.1 task Construct.
22666  // event-handle is a variable of the omp_event_handle_t type.
22667  auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22668  if (!Ref) {
22669  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22670  << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22671  return nullptr;
22672  }
22673  auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22674  if (!VD) {
22675  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22676  << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22677  return nullptr;
22678  }
22679  if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
22680  VD->getType()) ||
22681  VD->getType().isConstant(Context)) {
22682  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22683  << "omp_event_handle_t" << 1 << VD->getType()
22684  << Evt->getSourceRange();
22685  return nullptr;
22686  }
22687  // OpenMP 5.0, 2.10.1 task Construct
22688  // [detach clause]... The event-handle will be considered as if it was
22689  // specified on a firstprivate clause.
22690  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
22691  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22692  DVar.RefExpr) {
22693  Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
22694  << getOpenMPClauseName(DVar.CKind)
22695  << getOpenMPClauseName(OMPC_firstprivate);
22696  reportOriginalDsa(*this, DSAStack, VD, DVar);
22697  return nullptr;
22698  }
22699  }
22700 
22701  return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
22702 }
22703 
22705  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
22706  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
22707  SourceLocation EndLoc) {
22709  std::string Values;
22710  Values += "'";
22711  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
22712  Values += "'";
22713  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22714  << Values << getOpenMPClauseName(OMPC_dist_schedule);
22715  return nullptr;
22716  }
22717  Expr *ValExpr = ChunkSize;
22718  Stmt *HelperValStmt = nullptr;
22719  if (ChunkSize) {
22720  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
22721  !ChunkSize->isInstantiationDependent() &&
22722  !ChunkSize->containsUnexpandedParameterPack()) {
22723  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
22724  ExprResult Val =
22725  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
22726  if (Val.isInvalid())
22727  return nullptr;
22728 
22729  ValExpr = Val.get();
22730 
22731  // OpenMP [2.7.1, Restrictions]
22732  // chunk_size must be a loop invariant integer expression with a positive
22733  // value.
22734  if (std::optional<llvm::APSInt> Result =
22735  ValExpr->getIntegerConstantExpr(Context)) {
22736  if (Result->isSigned() && !Result->isStrictlyPositive()) {
22737  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22738  << "dist_schedule" << ChunkSize->getSourceRange();
22739  return nullptr;
22740  }
22742  DSAStack->getCurrentDirective(), OMPC_dist_schedule,
22743  LangOpts.OpenMP) != OMPD_unknown &&
22745  ValExpr = MakeFullExpr(ValExpr).get();
22746  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22747  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22748  HelperValStmt = buildPreInits(Context, Captures);
22749  }
22750  }
22751  }
22752 
22753  return new (Context)
22754  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
22755  Kind, ValExpr, HelperValStmt);
22756 }
22757 
22760  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
22761  SourceLocation KindLoc, SourceLocation EndLoc) {
22762  if (getLangOpts().OpenMP < 50) {
22763  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22764  Kind != OMPC_DEFAULTMAP_scalar) {
22766  SourceLocation Loc;
22767  Value += "'";
22768  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22769  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22770  OMPC_DEFAULTMAP_MODIFIER_tofrom);
22771  Loc = MLoc;
22772  } else {
22773  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22774  OMPC_DEFAULTMAP_scalar);
22775  Loc = KindLoc;
22776  }
22777  Value += "'";
22778  Diag(Loc, diag::err_omp_unexpected_clause_value)
22779  << Value << getOpenMPClauseName(OMPC_defaultmap);
22780  return nullptr;
22781  }
22782  } else {
22783  bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
22784  bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
22785  (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
22786  if (!isDefaultmapKind || !isDefaultmapModifier) {
22787  StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
22788  if (LangOpts.OpenMP == 50) {
22789  StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
22790  "'firstprivate', 'none', 'default'";
22791  if (!isDefaultmapKind && isDefaultmapModifier) {
22792  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22793  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22794  } else if (isDefaultmapKind && !isDefaultmapModifier) {
22795  Diag(MLoc, diag::err_omp_unexpected_clause_value)
22796  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22797  } else {
22798  Diag(MLoc, diag::err_omp_unexpected_clause_value)
22799  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22800  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22801  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22802  }
22803  } else {
22804  StringRef ModifierValue =
22805  "'alloc', 'from', 'to', 'tofrom', "
22806  "'firstprivate', 'none', 'default', 'present'";
22807  if (!isDefaultmapKind && isDefaultmapModifier) {
22808  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22809  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22810  } else if (isDefaultmapKind && !isDefaultmapModifier) {
22811  Diag(MLoc, diag::err_omp_unexpected_clause_value)
22812  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22813  } else {
22814  Diag(MLoc, diag::err_omp_unexpected_clause_value)
22815  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22816  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22817  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22818  }
22819  }
22820  return nullptr;
22821  }
22822 
22823  // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22824  // At most one defaultmap clause for each category can appear on the
22825  // directive.
22826  if (DSAStack->checkDefaultmapCategory(Kind)) {
22827  Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22828  return nullptr;
22829  }
22830  }
22831  if (Kind == OMPC_DEFAULTMAP_unknown) {
22832  // Variable category is not specified - mark all categories.
22833  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22834  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22835  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22836  } else {
22837  DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
22838  }
22839 
22840  return new (Context)
22841  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
22842 }
22843 
22845  DeclareTargetContextInfo &DTCI) {
22846  DeclContext *CurLexicalContext = getCurLexicalContext();
22847  if (!CurLexicalContext->isFileContext() &&
22848  !CurLexicalContext->isExternCContext() &&
22849  !CurLexicalContext->isExternCXXContext() &&
22850  !isa<CXXRecordDecl>(CurLexicalContext) &&
22851  !isa<ClassTemplateDecl>(CurLexicalContext) &&
22852  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22853  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22854  Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22855  return false;
22856  }
22857  DeclareTargetNesting.push_back(DTCI);
22858  return true;
22859 }
22860 
22861 const Sema::DeclareTargetContextInfo
22863  assert(!DeclareTargetNesting.empty() &&
22864  "check isInOpenMPDeclareTargetContext() first!");
22865  return DeclareTargetNesting.pop_back_val();
22866 }
22867 
22869  DeclareTargetContextInfo &DTCI) {
22870  for (auto &It : DTCI.ExplicitlyMapped)
22871  ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
22872 }
22873 
22875  if (DeclareTargetNesting.empty())
22876  return;
22877  DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22878  Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
22879  << getOpenMPDirectiveName(DTCI.Kind);
22880 }
22881 
22883  CXXScopeSpec &ScopeSpec,
22884  const DeclarationNameInfo &Id) {
22885  LookupResult Lookup(*this, Id, LookupOrdinaryName);
22886  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
22887 
22888  if (Lookup.isAmbiguous())
22889  return nullptr;
22890  Lookup.suppressDiagnostics();
22891 
22892  if (!Lookup.isSingleResult()) {
22893  VarOrFuncDeclFilterCCC CCC(*this);
22894  if (TypoCorrection Corrected =
22895  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
22896  CTK_ErrorRecovery)) {
22897  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
22898  << Id.getName());
22899  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
22900  return nullptr;
22901  }
22902 
22903  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
22904  return nullptr;
22905  }
22906 
22907  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
22908  if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
22909  !isa<FunctionTemplateDecl>(ND)) {
22910  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
22911  return nullptr;
22912  }
22913  return ND;
22914 }
22915 
22917  OMPDeclareTargetDeclAttr::MapTypeTy MT,
22918  DeclareTargetContextInfo &DTCI) {
22919  assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
22920  isa<FunctionTemplateDecl>(ND)) &&
22921  "Expected variable, function or function template.");
22922 
22923  // Diagnose marking after use as it may lead to incorrect diagnosis and
22924  // codegen.
22925  if (LangOpts.OpenMP >= 50 &&
22926  (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
22927  Diag(Loc, diag::warn_omp_declare_target_after_first_use);
22928 
22929  // Explicit declare target lists have precedence.
22930  const unsigned Level = -1;
22931 
22932  auto *VD = cast<ValueDecl>(ND);
22933  std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22934  OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22935  if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
22936  (*ActiveAttr)->getLevel() == Level) {
22937  Diag(Loc, diag::err_omp_device_type_mismatch)
22938  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22939  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22940  (*ActiveAttr)->getDevType());
22941  return;
22942  }
22943  if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
22944  (*ActiveAttr)->getLevel() == Level) {
22945  Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22946  return;
22947  }
22948 
22949  if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
22950  return;
22951 
22952  Expr *IndirectE = nullptr;
22953  bool IsIndirect = false;
22954  if (DTCI.Indirect) {
22955  IndirectE = *DTCI.Indirect;
22956  if (!IndirectE)
22957  IsIndirect = true;
22958  }
22959  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22960  Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22961  SourceRange(Loc, Loc));
22962  ND->addAttr(A);
22964  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22965  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22966 }
22967 
22969  Sema &SemaRef, Decl *D) {
22970  if (!D || !isa<VarDecl>(D))
22971  return;
22972  auto *VD = cast<VarDecl>(D);
22973  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
22974  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22975  if (SemaRef.LangOpts.OpenMP >= 50 &&
22976  (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22977  SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22978  VD->hasGlobalStorage()) {
22979  if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
22980  *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
22981  // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22982  // If a lambda declaration and definition appears between a
22983  // declare target directive and the matching end declare target
22984  // directive, all variables that are captured by the lambda
22985  // expression must also appear in a to clause.
22986  SemaRef.Diag(VD->getLocation(),
22987  diag::err_omp_lambda_capture_in_declare_target_not_to);
22988  SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22989  << VD << 0 << SR;
22990  return;
22991  }
22992  }
22993  if (MapTy)
22994  return;
22995  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22996  SemaRef.Diag(SL, diag::note_used_here) << SR;
22997 }
22998 
23000  Sema &SemaRef, DSAStackTy *Stack,
23001  ValueDecl *VD) {
23002  return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23003  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23004  /*FullCheck=*/false);
23005 }
23006 
23008  SourceLocation IdLoc) {
23009  if (!D || D->isInvalidDecl())
23010  return;
23011  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
23012  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
23013  if (auto *VD = dyn_cast<VarDecl>(D)) {
23014  // Only global variables can be marked as declare target.
23015  if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23016  !VD->isStaticDataMember())
23017  return;
23018  // 2.10.6: threadprivate variable cannot appear in a declare target
23019  // directive.
23020  if (DSAStack->isThreadPrivate(VD)) {
23021  Diag(SL, diag::err_omp_threadprivate_in_target);
23022  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23023  return;
23024  }
23025  }
23026  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23027  D = FTD->getTemplatedDecl();
23028  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23029  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23030  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23031  if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23032  Diag(IdLoc, diag::err_omp_function_in_link_clause);
23033  Diag(FD->getLocation(), diag::note_defined_here) << FD;
23034  return;
23035  }
23036  }
23037  if (auto *VD = dyn_cast<ValueDecl>(D)) {
23038  // Problem if any with var declared with incomplete type will be reported
23039  // as normal, so no need to check it here.
23040  if ((E || !VD->getType()->isIncompleteType()) &&
23041  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
23042  return;
23043  if (!E && isInOpenMPDeclareTargetContext()) {
23044  // Checking declaration inside declare target region.
23045  if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23046  isa<FunctionTemplateDecl>(D)) {
23047  std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23048  OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23049  unsigned Level = DeclareTargetNesting.size();
23050  if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23051  return;
23052  DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23053  Expr *IndirectE = nullptr;
23054  bool IsIndirect = false;
23055  if (DTCI.Indirect) {
23056  IndirectE = *DTCI.Indirect;
23057  if (!IndirectE)
23058  IsIndirect = true;
23059  }
23060  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23061  Context,
23062  getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23063  : OMPDeclareTargetDeclAttr::MT_To,
23064  DTCI.DT, IndirectE, IsIndirect, Level,
23065  SourceRange(DTCI.Loc, DTCI.Loc));
23066  D->addAttr(A);
23068  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23069  }
23070  return;
23071  }
23072  }
23073  if (!E)
23074  return;
23075  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23076 }
23077 
23079  ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23080  ArrayRef<SourceLocation> MotionModifiersLoc,
23081  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23082  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23083  const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23087 
23088  // Process motion-modifiers, flag errors for duplicate modifiers.
23089  unsigned Count = 0;
23090  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23091  if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23092  llvm::is_contained(Modifiers, MotionModifiers[I])) {
23093  Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23094  continue;
23095  }
23096  assert(Count < NumberOfOMPMotionModifiers &&
23097  "Modifiers exceed the allowed number of motion modifiers");
23098  Modifiers[Count] = MotionModifiers[I];
23099  ModifiersLoc[Count] = MotionModifiersLoc[I];
23100  ++Count;
23101  }
23102 
23103  MappableVarListInfo MVLI(VarList);
23104  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23105  MapperIdScopeSpec, MapperId, UnresolvedMappers);
23106  if (MVLI.ProcessedVarList.empty())
23107  return nullptr;
23108 
23109  return OMPToClause::Create(
23110  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23111  MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23112  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23113 }
23114 
23116  ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23117  ArrayRef<SourceLocation> MotionModifiersLoc,
23118  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23119  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23120  const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23124 
23125  // Process motion-modifiers, flag errors for duplicate modifiers.
23126  unsigned Count = 0;
23127  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23128  if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23129  llvm::is_contained(Modifiers, MotionModifiers[I])) {
23130  Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23131  continue;
23132  }
23133  assert(Count < NumberOfOMPMotionModifiers &&
23134  "Modifiers exceed the allowed number of motion modifiers");
23135  Modifiers[Count] = MotionModifiers[I];
23136  ModifiersLoc[Count] = MotionModifiersLoc[I];
23137  ++Count;
23138  }
23139 
23140  MappableVarListInfo MVLI(VarList);
23141  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23142  MapperIdScopeSpec, MapperId, UnresolvedMappers);
23143  if (MVLI.ProcessedVarList.empty())
23144  return nullptr;
23145 
23146  return OMPFromClause::Create(
23147  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23148  MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23149  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23150 }
23151 
23153  const OMPVarListLocTy &Locs) {
23154  MappableVarListInfo MVLI(VarList);
23155  SmallVector<Expr *, 8> PrivateCopies;
23156  SmallVector<Expr *, 8> Inits;
23157 
23158  for (Expr *RefExpr : VarList) {
23159  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23160  SourceLocation ELoc;
23161  SourceRange ERange;
23162  Expr *SimpleRefExpr = RefExpr;
23163  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23164  if (Res.second) {
23165  // It will be analyzed later.
23166  MVLI.ProcessedVarList.push_back(RefExpr);
23167  PrivateCopies.push_back(nullptr);
23168  Inits.push_back(nullptr);
23169  }
23170  ValueDecl *D = Res.first;
23171  if (!D)
23172  continue;
23173 
23174  QualType Type = D->getType();
23175  Type = Type.getNonReferenceType().getUnqualifiedType();
23176 
23177  auto *VD = dyn_cast<VarDecl>(D);
23178 
23179  // Item should be a pointer or reference to pointer.
23180  if (!Type->isPointerType()) {
23181  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23182  << 0 << RefExpr->getSourceRange();
23183  continue;
23184  }
23185 
23186  // Build the private variable and the expression that refers to it.
23187  auto VDPrivate =
23188  buildVarDecl(*this, ELoc, Type, D->getName(),
23189  D->hasAttrs() ? &D->getAttrs() : nullptr,
23190  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23191  if (VDPrivate->isInvalidDecl())
23192  continue;
23193 
23194  CurContext->addDecl(VDPrivate);
23195  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23196  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23197 
23198  // Add temporary variable to initialize the private copy of the pointer.
23199  VarDecl *VDInit =
23200  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23201  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23202  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23203  AddInitializerToDecl(VDPrivate,
23204  DefaultLvalueConversion(VDInitRefExpr).get(),
23205  /*DirectInit=*/false);
23206 
23207  // If required, build a capture to implement the privatization initialized
23208  // with the current list item value.
23209  DeclRefExpr *Ref = nullptr;
23210  if (!VD)
23211  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23212  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23213  PrivateCopies.push_back(VDPrivateRefExpr);
23214  Inits.push_back(VDInitRefExpr);
23215 
23216  // We need to add a data sharing attribute for this variable to make sure it
23217  // is correctly captured. A variable that shows up in a use_device_ptr has
23218  // similar properties of a first private variable.
23219  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23220 
23221  // Create a mappable component for the list item. List items in this clause
23222  // only need a component.
23223  MVLI.VarBaseDeclarations.push_back(D);
23224  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23225  MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23226  /*IsNonContiguous=*/false);
23227  }
23228 
23229  if (MVLI.ProcessedVarList.empty())
23230  return nullptr;
23231 
23233  Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23234  MVLI.VarBaseDeclarations, MVLI.VarComponents);
23235 }
23236 
23238  const OMPVarListLocTy &Locs) {
23239  MappableVarListInfo MVLI(VarList);
23240 
23241  for (Expr *RefExpr : VarList) {
23242  assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23243  SourceLocation ELoc;
23244  SourceRange ERange;
23245  Expr *SimpleRefExpr = RefExpr;
23246  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23247  /*AllowArraySection=*/true);
23248  if (Res.second) {
23249  // It will be analyzed later.
23250  MVLI.ProcessedVarList.push_back(RefExpr);
23251  }
23252  ValueDecl *D = Res.first;
23253  if (!D)
23254  continue;
23255  auto *VD = dyn_cast<VarDecl>(D);
23256 
23257  // If required, build a capture to implement the privatization initialized
23258  // with the current list item value.
23259  DeclRefExpr *Ref = nullptr;
23260  if (!VD)
23261  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23262  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23263 
23264  // We need to add a data sharing attribute for this variable to make sure it
23265  // is correctly captured. A variable that shows up in a use_device_addr has
23266  // similar properties of a first private variable.
23267  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23268 
23269  // Create a mappable component for the list item. List items in this clause
23270  // only need a component.
23271  MVLI.VarBaseDeclarations.push_back(D);
23272  MVLI.VarComponents.emplace_back();
23273  Expr *Component = SimpleRefExpr;
23274  if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23275  isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23276  Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23277  MVLI.VarComponents.back().emplace_back(Component, D,
23278  /*IsNonContiguous=*/false);
23279  }
23280 
23281  if (MVLI.ProcessedVarList.empty())
23282  return nullptr;
23283 
23284  return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23285  MVLI.VarBaseDeclarations,
23286  MVLI.VarComponents);
23287 }
23288 
23290  const OMPVarListLocTy &Locs) {
23291  MappableVarListInfo MVLI(VarList);
23292  for (Expr *RefExpr : VarList) {
23293  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23294  SourceLocation ELoc;
23295  SourceRange ERange;
23296  Expr *SimpleRefExpr = RefExpr;
23297  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23298  if (Res.second) {
23299  // It will be analyzed later.
23300  MVLI.ProcessedVarList.push_back(RefExpr);
23301  }
23302  ValueDecl *D = Res.first;
23303  if (!D)
23304  continue;
23305 
23306  QualType Type = D->getType();
23307  // item should be a pointer or array or reference to pointer or array
23308  if (!Type.getNonReferenceType()->isPointerType() &&
23309  !Type.getNonReferenceType()->isArrayType()) {
23310  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23311  << 0 << RefExpr->getSourceRange();
23312  continue;
23313  }
23314 
23315  // Check if the declaration in the clause does not show up in any data
23316  // sharing attribute.
23317  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23318  if (isOpenMPPrivate(DVar.CKind)) {
23319  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23320  << getOpenMPClauseName(DVar.CKind)
23321  << getOpenMPClauseName(OMPC_is_device_ptr)
23322  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23323  reportOriginalDsa(*this, DSAStack, D, DVar);
23324  continue;
23325  }
23326 
23327  const Expr *ConflictExpr;
23328  if (DSAStack->checkMappableExprComponentListsForDecl(
23329  D, /*CurrentRegionOnly=*/true,
23330  [&ConflictExpr](
23332  OpenMPClauseKind) -> bool {
23333  ConflictExpr = R.front().getAssociatedExpression();
23334  return true;
23335  })) {
23336  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23337  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23338  << ConflictExpr->getSourceRange();
23339  continue;
23340  }
23341 
23342  // Store the components in the stack so that they can be used to check
23343  // against other clauses later on.
23345  SimpleRefExpr, D, /*IsNonContiguous=*/false);
23346  DSAStack->addMappableExpressionComponents(
23347  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23348 
23349  // Record the expression we've just processed.
23350  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23351 
23352  // Create a mappable component for the list item. List items in this clause
23353  // only need a component. We use a null declaration to signal fields in
23354  // 'this'.
23355  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23356  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23357  "Unexpected device pointer expression!");
23358  MVLI.VarBaseDeclarations.push_back(
23359  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23360  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23361  MVLI.VarComponents.back().push_back(MC);
23362  }
23363 
23364  if (MVLI.ProcessedVarList.empty())
23365  return nullptr;
23366 
23367  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23368  MVLI.VarBaseDeclarations,
23369  MVLI.VarComponents);
23370 }
23371 
23373  const OMPVarListLocTy &Locs) {
23374  MappableVarListInfo MVLI(VarList);
23375  for (Expr *RefExpr : VarList) {
23376  assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23377  SourceLocation ELoc;
23378  SourceRange ERange;
23379  Expr *SimpleRefExpr = RefExpr;
23380  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23381  /*AllowArraySection=*/true);
23382  if (Res.second) {
23383  // It will be analyzed later.
23384  MVLI.ProcessedVarList.push_back(RefExpr);
23385  }
23386  ValueDecl *D = Res.first;
23387  if (!D)
23388  continue;
23389 
23390  // Check if the declaration in the clause does not show up in any data
23391  // sharing attribute.
23392  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23393  if (isOpenMPPrivate(DVar.CKind)) {
23394  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23395  << getOpenMPClauseName(DVar.CKind)
23396  << getOpenMPClauseName(OMPC_has_device_addr)
23397  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23398  reportOriginalDsa(*this, DSAStack, D, DVar);
23399  continue;
23400  }
23401 
23402  const Expr *ConflictExpr;
23403  if (DSAStack->checkMappableExprComponentListsForDecl(
23404  D, /*CurrentRegionOnly=*/true,
23405  [&ConflictExpr](
23407  OpenMPClauseKind) -> bool {
23408  ConflictExpr = R.front().getAssociatedExpression();
23409  return true;
23410  })) {
23411  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23412  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23413  << ConflictExpr->getSourceRange();
23414  continue;
23415  }
23416 
23417  // Store the components in the stack so that they can be used to check
23418  // against other clauses later on.
23419  Expr *Component = SimpleRefExpr;
23420  auto *VD = dyn_cast<VarDecl>(D);
23421  if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23422  isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23423  Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23425  Component, D, /*IsNonContiguous=*/false);
23426  DSAStack->addMappableExpressionComponents(
23427  D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23428 
23429  // Record the expression we've just processed.
23430  if (!VD && !CurContext->isDependentContext()) {
23431  DeclRefExpr *Ref =
23432  buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23433  assert(Ref && "has_device_addr capture failed");
23434  MVLI.ProcessedVarList.push_back(Ref);
23435  } else
23436  MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23437 
23438  // Create a mappable component for the list item. List items in this clause
23439  // only need a component. We use a null declaration to signal fields in
23440  // 'this'.
23441  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23442  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23443  "Unexpected device pointer expression!");
23444  MVLI.VarBaseDeclarations.push_back(
23445  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23446  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23447  MVLI.VarComponents.back().push_back(MC);
23448  }
23449 
23450  if (MVLI.ProcessedVarList.empty())
23451  return nullptr;
23452 
23453  return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23454  MVLI.VarBaseDeclarations,
23455  MVLI.VarComponents);
23456 }
23457 
23459  Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23460  SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23461  if (Allocator) {
23462  // OpenMP [2.11.4 allocate Clause, Description]
23463  // allocator is an expression of omp_allocator_handle_t type.
23464  if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23465  return nullptr;
23466 
23467  ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23468  if (AllocatorRes.isInvalid())
23469  return nullptr;
23470  AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23471  DSAStack->getOMPAllocatorHandleT(),
23473  /*AllowExplicit=*/true);
23474  if (AllocatorRes.isInvalid())
23475  return nullptr;
23476  Allocator = AllocatorRes.get();
23477  } else {
23478  // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23479  // allocate clauses that appear on a target construct or on constructs in a
23480  // target region must specify an allocator expression unless a requires
23481  // directive with the dynamic_allocators clause is present in the same
23482  // compilation unit.
23483  if (LangOpts.OpenMPIsDevice &&
23484  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23485  targetDiag(StartLoc, diag::err_expected_allocator_expression);
23486  }
23487  // Analyze and build list of variables.
23489  for (Expr *RefExpr : VarList) {
23490  assert(RefExpr && "NULL expr in OpenMP private clause.");
23491  SourceLocation ELoc;
23492  SourceRange ERange;
23493  Expr *SimpleRefExpr = RefExpr;
23494  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23495  if (Res.second) {
23496  // It will be analyzed later.
23497  Vars.push_back(RefExpr);
23498  }
23499  ValueDecl *D = Res.first;
23500  if (!D)
23501  continue;
23502 
23503  auto *VD = dyn_cast<VarDecl>(D);
23504  DeclRefExpr *Ref = nullptr;
23505  if (!VD && !CurContext->isDependentContext())
23506  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23507  Vars.push_back((VD || CurContext->isDependentContext())
23508  ? RefExpr->IgnoreParens()
23509  : Ref);
23510  }
23511 
23512  if (Vars.empty())
23513  return nullptr;
23514 
23515  if (Allocator)
23516  DSAStack->addInnerAllocatorExpr(Allocator);
23517  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23518  ColonLoc, EndLoc, Vars);
23519 }
23520 
23522  SourceLocation StartLoc,
23523  SourceLocation LParenLoc,
23524  SourceLocation EndLoc) {
23526  for (Expr *RefExpr : VarList) {
23527  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23528  SourceLocation ELoc;
23529  SourceRange ERange;
23530  Expr *SimpleRefExpr = RefExpr;
23531  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23532  if (Res.second)
23533  // It will be analyzed later.
23534  Vars.push_back(RefExpr);
23535  ValueDecl *D = Res.first;
23536  if (!D)
23537  continue;
23538 
23539  // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23540  // A list-item cannot appear in more than one nontemporal clause.
23541  if (const Expr *PrevRef =
23542  DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23543  Diag(ELoc, diag::err_omp_used_in_clause_twice)
23544  << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23545  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23546  << getOpenMPClauseName(OMPC_nontemporal);
23547  continue;
23548  }
23549 
23550  Vars.push_back(RefExpr);
23551  }
23552 
23553  if (Vars.empty())
23554  return nullptr;
23555 
23556  return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23557  Vars);
23558 }
23559 
23561  SourceLocation StartLoc,
23562  SourceLocation LParenLoc,
23563  SourceLocation EndLoc) {
23565  for (Expr *RefExpr : VarList) {
23566  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23567  SourceLocation ELoc;
23568  SourceRange ERange;
23569  Expr *SimpleRefExpr = RefExpr;
23570  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23571  /*AllowArraySection=*/true);
23572  if (Res.second)
23573  // It will be analyzed later.
23574  Vars.push_back(RefExpr);
23575  ValueDecl *D = Res.first;
23576  if (!D)
23577  continue;
23578 
23579  const DSAStackTy::DSAVarData DVar =
23580  DSAStack->getTopDSA(D, /*FromParent=*/true);
23581  // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23582  // A list item that appears in the inclusive or exclusive clause must appear
23583  // in a reduction clause with the inscan modifier on the enclosing
23584  // worksharing-loop, worksharing-loop SIMD, or simd construct.
23585  if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23586  Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23587  << RefExpr->getSourceRange();
23588 
23589  if (DSAStack->getParentDirective() != OMPD_unknown)
23590  DSAStack->markDeclAsUsedInScanDirective(D);
23591  Vars.push_back(RefExpr);
23592  }
23593 
23594  if (Vars.empty())
23595  return nullptr;
23596 
23597  return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23598 }
23599 
23601  SourceLocation StartLoc,
23602  SourceLocation LParenLoc,
23603  SourceLocation EndLoc) {
23605  for (Expr *RefExpr : VarList) {
23606  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23607  SourceLocation ELoc;
23608  SourceRange ERange;
23609  Expr *SimpleRefExpr = RefExpr;
23610  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23611  /*AllowArraySection=*/true);
23612  if (Res.second)
23613  // It will be analyzed later.
23614  Vars.push_back(RefExpr);
23615  ValueDecl *D = Res.first;
23616  if (!D)
23617  continue;
23618 
23619  OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
23620  DSAStackTy::DSAVarData DVar;
23621  if (ParentDirective != OMPD_unknown)
23622  DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
23623  // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23624  // A list item that appears in the inclusive or exclusive clause must appear
23625  // in a reduction clause with the inscan modifier on the enclosing
23626  // worksharing-loop, worksharing-loop SIMD, or simd construct.
23627  if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23628  DVar.Modifier != OMPC_REDUCTION_inscan) {
23629  Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23630  << RefExpr->getSourceRange();
23631  } else {
23632  DSAStack->markDeclAsUsedInScanDirective(D);
23633  }
23634  Vars.push_back(RefExpr);
23635  }
23636 
23637  if (Vars.empty())
23638  return nullptr;
23639 
23640  return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23641 }
23642 
23643 /// Tries to find omp_alloctrait_t type.
23644 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
23645  QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23646  if (!OMPAlloctraitT.isNull())
23647  return true;
23648  IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
23649  ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
23650  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23651  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
23652  return false;
23653  }
23654  Stack->setOMPAlloctraitT(PT.get());
23655  return true;
23656 }
23657 
23659  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
23661  // OpenMP [2.12.5, target Construct]
23662  // allocator is an identifier of omp_allocator_handle_t type.
23663  if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
23664  return nullptr;
23665  // OpenMP [2.12.5, target Construct]
23666  // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23667  if (llvm::any_of(
23668  Data,
23669  [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
23670  !findOMPAlloctraitT(*this, StartLoc, DSAStack))
23671  return nullptr;
23672  llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
23673  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23674  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
23675  StringRef Allocator =
23676  OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23677  DeclarationName AllocatorName = &Context.Idents.get(Allocator);
23678  PredefinedAllocators.insert(LookupSingleName(
23679  TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
23680  }
23681 
23683  for (const UsesAllocatorsData &D : Data) {
23684  Expr *AllocatorExpr = nullptr;
23685  // Check allocator expression.
23686  if (D.Allocator->isTypeDependent()) {
23687  AllocatorExpr = D.Allocator;
23688  } else {
23689  // Traits were specified - need to assign new allocator to the specified
23690  // allocator, so it must be an lvalue.
23691  AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
23692  auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23693  bool IsPredefinedAllocator = false;
23694  if (DRE) {
23695  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
23696  getAllocatorKind(*this, DSAStack, AllocatorExpr);
23697  IsPredefinedAllocator =
23698  AllocatorTy !=
23699  OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
23700  }
23701  QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
23702  QualType AllocatorExprType = AllocatorExpr->getType();
23703  bool IsTypeCompatible = IsPredefinedAllocator;
23704  IsTypeCompatible = IsTypeCompatible ||
23705  Context.hasSameUnqualifiedType(AllocatorExprType,
23706  OMPAllocatorHandleT);
23707  IsTypeCompatible =
23708  IsTypeCompatible ||
23709  Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
23710  bool IsNonConstantLValue =
23711  !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
23712  if (!DRE || !IsTypeCompatible ||
23713  (!IsPredefinedAllocator && !IsNonConstantLValue)) {
23714  Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
23715  << "omp_allocator_handle_t" << (DRE ? 1 : 0)
23716  << AllocatorExpr->getType() << D.Allocator->getSourceRange();
23717  continue;
23718  }
23719  // OpenMP [2.12.5, target Construct]
23720  // Predefined allocators appearing in a uses_allocators clause cannot have
23721  // traits specified.
23722  if (IsPredefinedAllocator && D.AllocatorTraits) {
23724  diag::err_omp_predefined_allocator_with_traits)
23726  Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
23727  << cast<NamedDecl>(DRE->getDecl())->getName()
23728  << D.Allocator->getSourceRange();
23729  continue;
23730  }
23731  // OpenMP [2.12.5, target Construct]
23732  // Non-predefined allocators appearing in a uses_allocators clause must
23733  // have traits specified.
23734  if (!IsPredefinedAllocator && !D.AllocatorTraits) {
23735  Diag(D.Allocator->getExprLoc(),
23736  diag::err_omp_nonpredefined_allocator_without_traits);
23737  continue;
23738  }
23739  // No allocator traits - just convert it to rvalue.
23740  if (!D.AllocatorTraits)
23741  AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
23742  DSAStack->addUsesAllocatorsDecl(
23743  DRE->getDecl(),
23744  IsPredefinedAllocator
23745  ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23746  : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23747  }
23748  Expr *AllocatorTraitsExpr = nullptr;
23749  if (D.AllocatorTraits) {
23750  if (D.AllocatorTraits->isTypeDependent()) {
23751  AllocatorTraitsExpr = D.AllocatorTraits;
23752  } else {
23753  // OpenMP [2.12.5, target Construct]
23754  // Arrays that contain allocator traits that appear in a uses_allocators
23755  // clause must be constant arrays, have constant values and be defined
23756  // in the same scope as the construct in which the clause appears.
23757  AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
23758  // Check that traits expr is a constant array.
23759  QualType TraitTy;
23760  if (const ArrayType *Ty =
23761  AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
23762  if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23763  TraitTy = ConstArrayTy->getElementType();
23764  if (TraitTy.isNull() ||
23765  !(Context.hasSameUnqualifiedType(TraitTy,
23766  DSAStack->getOMPAlloctraitT()) ||
23767  Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
23768  /*CompareUnqualified=*/true))) {
23770  diag::err_omp_expected_array_alloctraits)
23771  << AllocatorTraitsExpr->getType();
23772  continue;
23773  }
23774  // Do not map by default allocator traits if it is a standalone
23775  // variable.
23776  if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23777  DSAStack->addUsesAllocatorsDecl(
23778  DRE->getDecl(),
23779  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23780  }
23781  }
23782  OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
23783  NewD.Allocator = AllocatorExpr;
23784  NewD.AllocatorTraits = AllocatorTraitsExpr;
23785  NewD.LParenLoc = D.LParenLoc;
23786  NewD.RParenLoc = D.RParenLoc;
23787  }
23788  return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23789  NewData);
23790 }
23791 
23793  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23794  SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
23796  for (Expr *RefExpr : Locators) {
23797  assert(RefExpr && "NULL expr in OpenMP shared clause.");
23798  if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23799  // It will be analyzed later.
23800  Vars.push_back(RefExpr);
23801  continue;
23802  }
23803 
23804  SourceLocation ELoc = RefExpr->getExprLoc();
23805  Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
23806 
23807  if (!SimpleExpr->isLValue()) {
23808  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23809  << 1 << 0 << RefExpr->getSourceRange();
23810  continue;
23811  }
23812 
23813  ExprResult Res;
23814  {
23815  Sema::TentativeAnalysisScope Trap(*this);
23816  Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
23817  }
23818  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
23819  !isa<OMPArrayShapingExpr>(SimpleExpr)) {
23820  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23821  << 1 << 0 << RefExpr->getSourceRange();
23822  continue;
23823  }
23824  Vars.push_back(SimpleExpr);
23825  }
23826 
23827  return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
23828  EndLoc, Modifier, Vars);
23829 }
23830 
23832  SourceLocation KindLoc,
23833  SourceLocation StartLoc,
23834  SourceLocation LParenLoc,
23835  SourceLocation EndLoc) {
23836  if (Kind == OMPC_BIND_unknown) {
23837  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23838  << getListOfPossibleValues(OMPC_bind, /*First=*/0,
23839  /*Last=*/unsigned(OMPC_BIND_unknown))
23840  << getOpenMPClauseName(OMPC_bind);
23841  return nullptr;
23842  }
23843 
23844  return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
23845  EndLoc);
23846 }
23847 
23849  SourceLocation StartLoc,
23850  SourceLocation LParenLoc,
23851  SourceLocation EndLoc) {
23852  Expr *ValExpr = Size;
23853  Stmt *HelperValStmt = nullptr;
23854 
23855  // OpenMP [2.5, Restrictions]
23856  // The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
23857  // value.
23858  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
23859  /*StrictlyPositive=*/false))
23860  return nullptr;
23861 
23862  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
23864  DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
23865  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
23866  ValExpr = MakeFullExpr(ValExpr).get();
23867  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23868  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
23869  HelperValStmt = buildPreInits(Context, Captures);
23870  }
23871 
23872  return new (Context) OMPXDynCGroupMemClause(
23873  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23874 }
clang::Decl::setLexicalDeclContext
void setLexicalDeclContext(DeclContext *DC)
Definition: DeclBase.cpp:340
clang::StmtVisitor
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
clang::Sema::ActOnOpenMPDepobjClause
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
Definition: SemaOpenMP.cpp:20483
clang::SourceRange::setBegin
void setBegin(SourceLocation b)
Definition: SourceLocation.h:222
clang::OpenMPDeviceClauseModifier
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition: OpenMPKinds.h:47
clang::OMPLoopBasedDirective::HelperExprs::IterationVarRef
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:743
clang::Sema::ActOnOpenMPDeclareReductionCombinerStart
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Definition: SemaOpenMP.cpp:22184
clang::Sema::ActOnOpenMPOrderedClause
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Definition: SemaOpenMP.cpp:16606
filterLookupForUDReductionAndMapper
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
Definition: SemaOpenMP.cpp:18713
clang::interp::APFloat
llvm::APFloat APFloat
Definition: Floating.h:23
clang::OMPClause::getClauseKind
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:83
clang::OMPPartialClause
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:907
clang::ASTContext::getTypeSizeInChars
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Definition: ASTContext.cpp:2560
clang::OMPClauseMappableExprCommon::MappableComponent
Class that represents a component of a mappable expression.
Definition: OpenMPClause.h:5095
clang::isOpenMPTargetDataManagementDirective
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
Definition: OpenMPKinds.cpp:634
clang::Sema::CurContext
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:421
clang::AssertSuccess
Expr * AssertSuccess(ExprResult R)
Definition: Ownership.h:292
clang::QualType::isMoreQualifiedThan
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:6815
clang::OMPAtClause
This represents 'at' clause in the '#pragma omp error' directive.
Definition: OpenMPClause.h:1412
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::Cond
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:723
clang::Sema::ActOnOpenMPVarListClause
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
Definition: SemaOpenMP.cpp:17777
actOnOMPReductionKindClause
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions, ReductionData &RD)
Definition: SemaOpenMP.cpp:19091
clang::OMPClauseMappableExprCommon::MappableComponent::getAssociatedDeclaration
ValueDecl * getAssociatedDeclaration() const
Definition: OpenMPClause.h:5125
checkCancelRegion
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
Definition: SemaOpenMP.cpp:4966
clang::Sema::ActOnOpenMPDistributeDirective
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13879
isNonNegativeIntegerValue
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
Definition: SemaOpenMP.cpp:16370
clang::Type::isRecordType
bool isRecordType() const
Definition: Type.h:6986
argumentDependentLookup
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
Definition: SemaOpenMP.cpp:18741
clang::OMPLoopBasedDirective::HelperExprs::PrevEUB
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e....
Definition: StmtOpenMP.h:787
clang::OpaquePtr::get
PtrTy get() const
Definition: Ownership.h:80
max
__DEVICE__ int max(int __a, int __b)
Definition: __clang_cuda_math.h:196
clang::ASTContext::getASTMutationListener
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
Definition: ASTContext.h:1180
clang::OMPOrderedClause::Create
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
Definition: OpenMPClause.cpp:340
clang::Sema::isOpenMPGlobalCapturedDecl
bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified global variable must be captured by outer capture regions.
Definition: SemaOpenMP.cpp:2651
clang::Type::getAsArrayTypeUnsafe
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7463
clang::ImaginaryLiteral
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1730
buildVarDecl
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:1528
checkScheduleModifiers
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
Definition: SemaOpenMP.cpp:17146
clang::OMPDestroyClause
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
Definition: OpenMPClause.h:8015
clang::Sema::ActOnOpenMPRegionEnd
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
Definition: SemaOpenMP.cpp:4791
clang::Sema::ActOnStartOpenMPDeclareTargetContext
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
Definition: SemaOpenMP.cpp:22844
clang::Sema::ActOnOpenMPSimpleClause
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:16631
clang::Sema::ActOnOpenMPWriteClause
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
Definition: SemaOpenMP.cpp:17426
clang::CorrectionCandidateCallback::ValidateCandidate
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
Definition: SemaLookup.cpp:5568
clang::Sema::ActOnCapturedRegionEnd
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:4804
clang::OMPCriticalDirective::Create
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:564
checkPreviousOMPAllocateAttribute
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
Definition: SemaOpenMP.cpp:3300
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2448
clang::Sema::CheckPlaceholderExpr
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20947
clang::VarDecl::getStorageDuration
StorageDuration getStorageDuration() const
Get the storage duration of this variable, per C++ [basic.stc].
Definition: Decl.h:1188
clang::OMPTargetSimdDirective::Create
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1785
clang::ASTContext::getTypeDeclType
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1554
clang::VarDecl::getSourceRange
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2118
clang::Sema::ActOnOpenMPCaptureClause
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
Definition: SemaOpenMP.cpp:17436
clang::OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
@ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
Definition: OpenMPKinds.h:131
clang::FunctionDecl::getNumParams
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3473
clang::VarDecl::isFileVarDecl
bool isFileVarDecl() const
Returns true for file scoped variable declaration.
Definition: Decl.h:1301
clang::Sema::ActOnOpenMPMessageClause
OMPClause * ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'message' clause.
Definition: SemaOpenMP.cpp:16877
clang::OMPCancellationPointDirective::Create
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:804
clang::DeclContext::decls
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2184
clang::Decl::setDeclContext
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition: DeclBase.cpp:336
clang::OMPUsesAllocatorsClause::Data::Allocator
Expr * Allocator
Allocator.
Definition: OpenMPClause.h:8384
clang::VarDecl::getTLSKind
TLSKind getTLSKind() const
Definition: Decl.cpp:2096
setPrototype
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
Definition: SemaOpenMP.cpp:7090
clang::Sema::ActOnOpenMPGrainsizeClause
OMPClause * ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
Definition: SemaOpenMP.cpp:22560
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:29
clang::Sema::CleanupVarDeclMarking
void CleanupVarDeclMarking()
Definition: SemaExpr.cpp:19697
clang::Sema::ActOnOpenMPMaskedTaskLoopDirective
StmtResult ActOnOpenMPMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13489
DSAStack
#define DSAStack
Definition: SemaOpenMP.cpp:2005
TreeTransform.h
clang::OK_Ordinary
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:139
clang::OMPLastprivateClause::Create
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:510
clang::Sema::UsesAllocatorsData::LParenLoc
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Definition: Sema.h:12175
clang::TypeSourceInfo::getType
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6617
clang::CXXRewrittenBinaryOperator::DecomposedForm
Definition: ExprCXX.h:304
clang::isOpenMPNestingTeamsDirective
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Definition: OpenMPKinds.cpp:639
clang::OMPDispatchDirective::Create
static OMPDispatchDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, SourceLocation TargetCallLoc)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2277
clang::Sema::ActOnOpenMPFilterClause
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
Definition: SemaOpenMP.cpp:17756
clang::OMPTeamsGenericLoopDirective::Create
static OMPTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2354
clang::Sema::BuildDeclRefExpr
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2001
clang::OMPTeamsDirective::Create
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1046
clang::OMPSeverityClause
This represents 'severity' clause in the '#pragma omp error' directive.
Definition: OpenMPClause.h:1491
clang::OMPPriorityClause
This represents 'priority' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6151
clang::CXXRewrittenBinaryOperator::DecomposedForm::LHS
const Expr * LHS
The original left-hand side.
Definition: ExprCXX.h:308
clang::OMPDeclareReductionDecl::CallInit
@ CallInit
Definition: DeclOpenMP.h:176
clang::OMPLoopBasedDirective::HelperExprs::LB
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:761
clang::for
for(unsigned I=0, E=TL.getNumArgs();I !=E;++I)
Definition: RecursiveASTVisitor.h:1384
clang::CallExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:1620
clang::Expr::isLValue
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:272
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::Init
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
Definition: StmtOpenMP.h:720
clang::Sema::ActOnOpenMPExclusiveClause
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
Definition: SemaOpenMP.cpp:23600
Error
llvm::Error Error
Definition: ByteCodeEmitter.cpp:21
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::ParForInDistCond
Expr * ParForInDistCond
'omp parallel for' loop condition used when composed with 'omp distribute' in the same construct and ...
Definition: StmtOpenMP.h:736
clang::DeclContext::addHiddenDecl
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1581
clang::OMPScheduleClause::getSecondScheduleModifier
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
Definition: OpenMPClause.h:1772
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:23
clang::OMPLoopBasedDirective::HelperExprs::Counters
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:789
clang::LookupResult::end
iterator end() const
Definition: Lookup.h:336
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1389
clang::OMPLoopBasedDirective::HelperExprs::DistInc
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e....
Definition: StmtOpenMP.h:781
clang::Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope
void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl *D, SmallVectorImpl< FunctionDecl * > &Bases)
Register D as specialization of all base functions in Bases in the current omp begin/end declare vari...
Definition: SemaOpenMP.cpp:7220
clang::Sema::ActOnOpenMPRequiresDirective
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
Definition: SemaOpenMP.cpp:3451
clang::Sema::ActOnOpenMPFullClause
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
Definition: SemaOpenMP.cpp:16966
advance
static ParseState advance(ParseState S, size_t N)
Definition: Parsing.cpp:144
clang::LambdaCapture
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
clang::CXXConversionDecl
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2778
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:560
clang::VarDecl::hasGlobalStorage
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1185
clang::LookupResult::isSingleResult
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:308
checkMapClauseExpressionBase
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose)
Return the expression of the base of the mappable expression or null if it cannot be determined and d...
Definition: SemaOpenMP.cpp:21287
clang::TypoCorrection
Simple class containing the result of Sema::CorrectTypo.
Definition: TypoCorrection.h:42
Data
const char * Data
Definition: StandardLibrary.cpp:35
clang::Sema::ActOnOpenMPTargetDirective
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12955
clang::PartialDiagnostic::NullDiagnostic
Definition: PartialDiagnostic.h:40
clang::Sema::isOpenMPTargetCapturedDecl
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified variable is captured by 'target' directive.
Definition: SemaOpenMP.cpp:2637
clang::Sema::getASTContext
ASTContext & getASTContext() const
Definition: Sema.h:1662
clang::VarDecl::getCanonicalDecl
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2186
clang::Sema::isOpenMPCapturedDecl
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate,...
Definition: SemaOpenMP.cpp:2327
clang::Sema::ActOnOpenMPSafelenClause
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
Definition: SemaOpenMP.cpp:16486
clang::Sema::getCurFunction
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1987
clang::Sema::SemaDiagnosticBuilder::Kind
Kind
Definition: Sema.h:1772
clang::Sema::ActOnOpenMPDetachClause
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
Definition: SemaOpenMP.cpp:22657
clang::Sema::ActOnOpenMPNovariantsClause
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
Definition: SemaOpenMP.cpp:17694
clang::FunctionDecl::isConstexpr
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
Definition: Decl.h:2367
clang::Sema::ActOnOpenMPTaskReductionClause
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'task_reduction' clause.
Definition: SemaOpenMP.cpp:19847
clang::OpenMPAtClauseKind
OpenMPAtClauseKind
OpenMP attributes for 'at' clause.
Definition: OpenMPKinds.h:135
Diag
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Definition: LiteralSupport.cpp:79
clang::Sema::ActOnOpenMPFromClause
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'from' clause.
Definition: SemaOpenMP.cpp:23115
clang::Sema::checkDeclIsAllowedInOpenMPTarget
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
Definition: SemaOpenMP.cpp:23007
getAllocatorKind
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
Definition: SemaOpenMP.cpp:3275
clang::OMPFromClause::Create
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1242
SemaInternal.h
clang::isOpenMPParallelDirective
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
Definition: OpenMPKinds.cpp:604
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::UB
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:713
clang::Sema::forRedeclarationInCurContext
RedeclarationKind forRedeclarationInCurContext()
Definition: Sema.h:4351
clang::Expr::IgnoreImplicit
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3024
clang::ASTContext::VoidTy
CanQualType VoidTy
Definition: ASTContext.h:1078
clang::Sema::ActOnOpenMPTargetParallelGenericLoopDirective
StmtResult ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10722
clang::OMPTargetParallelForDirective::Create
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:957
llvm::SmallVector
Definition: LLVM.h:35
clang::APValue::getInt
APSInt & getInt()
Definition: APValue.h:415
clang::Sema::UsesAllocatorsData::Allocator
Expr * Allocator
Allocator.
Definition: Sema.h:12171
clang::OMPDefaultmapClause
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6630
clang::OMPLoopBasedDirective::HelperExprs::IL
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:759
Lookup.h
clang::IdentifierTable::get
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Definition: IdentifierTable.h:597
clang::if
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Definition: RecursiveASTVisitor.h:1081
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::Sema::ActOnOpenMPDeclareReductionType
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
Definition: SemaOpenMP.cpp:22070
getCanonicalDecl
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
Definition: SemaOpenMP.cpp:1250
clang::Sema::FunctionScopes
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:805
clang::OMPThreadPrivateDecl
This represents '#pragma omp threadprivate ...' directive.
Definition: DeclOpenMP.h:110
checkDeclInTargetContext
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Definition: SemaOpenMP.cpp:22968
clang::OMPUsesAllocatorsClause::Data::RParenLoc
SourceLocation RParenLoc
Definition: OpenMPClause.h:8388
clang::ASTContext::getIntWidth
unsigned getIntWidth(QualType T) const
Definition: ASTContext.cpp:10982
clang::ActionResult::getAs
T * getAs()
Definition: Ownership.h:170
clang::Sema::ActOnOpenMPParallelDirective
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:7734
clang::OMPDepobjClause::Create
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
Definition: OpenMPClause.cpp:1035
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:247
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::Sema::getEnclosingFunction
sema::FunctionScopeInfo * getEnclosingFunction() const
Definition: Sema.cpp:2318
clang::CompoundStmt::Create
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Definition: Stmt.cpp:382
clang::Sema::ActOnOpenMPSeverityClause
OMPClause * ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'severity' clause.
Definition: SemaOpenMP.cpp:16861
clang::OMPDepobjDirective::Create
static OMPDepobjDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:849
clang::OMPThreadsClause
This represents 'threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:5032
clang::DeclGroupRef::Create
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:68
clang::VarDecl::setInit
void setInit(Expr *I)
Definition: Decl.cpp:2383
clang::OMPC_AT_unknown
@ OMPC_AT_unknown
Definition: OpenMPKinds.h:138
clang::OMPAllocatorClause
This represents 'allocator' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:353
clang::OMPC_DEPEND_unknown
@ OMPC_DEPEND_unknown
Definition: OpenMPKinds.h:58
clang::OMPIfClause
This represents 'if' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:527
clang::TreeTransform
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
Definition: TreeTransform.h:102
TargetInfo.h
clang::OMPLinearClause::privates
privates_range privates()
Definition: OpenMPClause.h:4089
clang::LookupResult::clear
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
Definition: Lookup.h:580
clang::QualType::getNonReferenceType
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:6844
CXXInheritance.h
clang::OMPLinearClause
This represents clause 'linear' in the '#pragma omp ...' directives.
Definition: OpenMPClause.h:3904
checkOrderedOrderSpecified
static bool checkOrderedOrderSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:4761
clang::ASTContext::DeclarationNames
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:635
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
clang::Sema::ActOnOpenMPNogroupClause
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
Definition: SemaOpenMP.cpp:17481
clang::isOpenMPThreadPrivate
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate',...
Definition: OpenMPKinds.cpp:703
clang::OMPTraitInfo
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
Definition: OpenMPClause.h:8789
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:736
clang::Expr::getObjectKind
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:439
clang::OMPSharedClause::Create
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:534
clang::Type::isScalarType
bool isScalarType() const
Definition: Type.h:7291
clang::OMPFlushDirective::Create
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:834
clang::OMPSizesClause::getSizesRefs
MutableArrayRef< Expr * > getSizesRefs()
Returns the tile size expressions.
Definition: OpenMPClause.h:831
clang::OMPVarListClause::varlist_size
unsigned varlist_size() const
Definition: OpenMPClause.h:316
clang::FunctionDecl::getParamDecl
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2607
clang::Type::isFunctionNoProtoType
bool isFunctionNoProtoType() const
Definition: Type.h:2148
clang::Sema::LookupAnyName
@ LookupAnyName
Look up any declaration with any name.
Definition: Sema.h:4333
clang::Declarator::getIdentifier
IdentifierInfo * getIdentifier() const
Definition: DeclSpec.h:2251
clang::Sema::isOpenMPRebuildMemberExpr
bool isOpenMPRebuildMemberExpr(ValueDecl *D)
The member expression(this->fd) needs to be rebuilt in the template instantiation to generate private...
Definition: SemaOpenMP.cpp:2304
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:56
clang::DeclarationNameInfo::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclarationName.h:876
clang::DynamicInitKind::Initializer
@ Initializer
clang::OMPParallelDirective::Create
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:281
clang::CapturedDecl::getNumParams
unsigned getNumParams() const
Definition: Decl.h:4566
clang::OMPCompareClause
This represents 'compare' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2277
clang::BinaryOperator::getOpForCompoundAssignment
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3961
clang::tooling::Filter
llvm::cl::opt< std::string > Filter
clang::ArraySubscriptExpr::getIdx
Expr * getIdx()
Definition: Expr.h:2697
clang::Sema::ActOnOpenMPTargetSimdDirective
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:14116
clang::OMPUpdateClause::Create
static OMPUpdateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates clause for 'atomic' directive.
Definition: OpenMPClause.cpp:391
clang::sema::FunctionScopeInfo::setHasOMPDeclareReductionCombiner
void setHasOMPDeclareReductionCombiner()
Definition: ScopeInfo.h:443
isClauseMappable
static bool isClauseMappable(ArrayRef< OMPClause * > Clauses)
Check if the variables in the mapping clause are externally visible.
Definition: SemaOpenMP.cpp:13120
clang::OMPScheduleClause::getFirstScheduleModifierLoc
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:1783
clang::ASTContext::getFloatTypeSemantics
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
Definition: ASTContext.cpp:1750
clang::NumberOfOMPMotionModifiers
static constexpr unsigned NumberOfOMPMotionModifiers
Number of allowed motion-modifiers.
Definition: OpenMPKinds.h:99
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6687
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2943
clang::Sema::BuildBinOp
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:15628
clang::Sema::FilterLookupForScope
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.
Definition: SemaDecl.cpp:1617
clang::Type::isFloatingType
bool isFloatingType() const
Definition: Type.cpp:2145
clang::Sema::CheckOMPRequiresDecl
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause * > Clauses)
Check restrictions on Requires directive.
Definition: SemaOpenMP.cpp:3523
clang::BinaryOperator::reverseComparisonOp
static Opcode reverseComparisonOp(Opcode Opc)
Definition: Expr.h:3933
clang::LookupResult
Represents the results of name lookup.
Definition: Lookup.h:46
clang::ASTContext::getBaseElementType
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Definition: ASTContext.cpp:7031
clang::OMPTargetDirective::Create
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:923
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1724
clang::OpenMPReductionClauseModifier
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
Definition: OpenMPKinds.h:186
clang::Sema::Diag
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1877
clang::Sema::GetTypeForDeclarator
TypeSourceInfo * GetTypeForDeclarator(Declarator &D, Scope *S)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
Definition: SemaType.cpp:5924
clang::Sema::TUScope
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:1133
clang::OMPLoopBasedDirective::HelperExprs::Inits
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:793
DeclCXX.h
clang::ASTContext::getFunctionType
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1532
clang::Decl::isUsed
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
Definition: DeclBase.cpp:457
clang::Sema::VerifyIntegerConstantExpression
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
Definition: SemaExpr.cpp:17467
clang::Sema::ActOnOpenMPIfClause
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
Definition: SemaOpenMP.cpp:16260
clang::isOpenMPLoopDirective
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Definition: OpenMPKinds.cpp:551
clang::OMPC_ORDER_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_unknown
Definition: OpenMPKinds.h:172
checkIfClauses
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
Definition: SemaOpenMP.cpp:5270
clang::OMPAtomicDefaultMemOrderClause
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1323
clang::BinaryOperator::getExprLoc
SourceLocation getExprLoc() const
Definition: Expr.h:3855
clang::OMPAllocateClause::Create
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1000
clang::FunctionProtoType::ExtProtoInfo::Variadic
bool Variadic
Definition: Type.h:4108
clang::isOpenMPCombinedParallelADirective
bool isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a combined construct for which the first construct is a parallel...
Definition: OpenMPKinds.cpp:724
clang::Sema::DiscardCleanupsInEvaluationContext
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:18037
clang::OMPDistScheduleClause
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6511
clang::Sema::ActOnOpenMPForDirective
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10330
clang::Type::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2005
clang::Expr::EvalStatus::Diag
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Definition: Expr.h:611
clang::IfStmt
IfStmt - This represents an if/then/else.
Definition: Stmt.h:1948
clang::ExprObjectKind
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:137
clang::Sema::ActOnOpenMPDeclareMapperVarDecl
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
Definition: SemaOpenMP.cpp:22327
clang::Sema::ActOnOpenMPGenericLoopDirective
StmtResult ActOnOpenMPGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10540
clang::Sema::CreateBuiltinBinOp
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
Definition: SemaExpr.cpp:15106
clang::OMPDistributeDirective::Create
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1515
DeclOpenMP.h
clang::Sema::ActOnOpenMPCopyprivateClause
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Definition: SemaOpenMP.cpp:20344
clang::OMPInteropDirective::Create
static OMPInteropDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
Definition: StmtOpenMP.cpp:2263
clang::Type::isRealFloatingType
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2161
clang::Sema::LookupQualifiedName
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Definition: SemaLookup.cpp:2418
clang::OMPSeqCstClause
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2318
clang::OMPLinearClause::getStep
Expr * getStep()
Returns linear step.
Definition: OpenMPClause.h:4062
clang::OMPLoopBasedDirective::HelperExprs::DependentCounters
SmallVector< Expr *, 4 > DependentCounters
List of counters required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:800
clang::OpenMPMapClauseKind
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:70
clang::Sema::ActOnOpenMPDefaultmapClause
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
Definition: SemaOpenMP.cpp:22758
clang::Sema::ActOnOpenMPDestroyClause
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
Definition: SemaOpenMP.cpp:17674
clang::OMPC_LASTPRIVATE_unknown
@ OMPC_LASTPRIVATE_unknown
Definition: OpenMPKinds.h:160
clang::OMPLoopBasedDirective::HelperExprs::FinalsConditions
SmallVector< Expr *, 4 > FinalsConditions
List of final conditions required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:806
clang::OMPLoopTransformationDirective
The base class for all loop transformation directives.
Definition: StmtOpenMP.h:960
clang::ComparisonCategoryType::First
@ First
clang::OMPLinearClause::setFinals
void setFinals(ArrayRef< Expr * > FL)
Sets the list of final update expressions for linear variables.
Definition: OpenMPClause.cpp:569
clang::OMPUsesAllocatorsClause::Data::LParenLoc
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Definition: OpenMPClause.h:8388
clang::OMPC_REDUCTION_unknown
@ OMPC_REDUCTION_unknown
Definition: OpenMPKinds.h:189
clang::Sema::BuildBasePathArray
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
Definition: SemaDeclCXX.cpp:2945
clang::ActionResult::isUnset
bool isUnset() const
Definition: Ownership.h:167
llvm::SmallPtrSet
Definition: ASTContext.h:55
clang::OMPTaskLoopDirective::Create
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1062
clang::UnaryOperator
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2175
clang::Sema::ActOnOpenMPScanDirective
StmtResult ActOnOpenMPScanDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scan'.
Definition: SemaOpenMP.cpp:11239
clang::Sema::ActOnOpenMPErrorDirective
StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)
Called on well-formed '#pragma omp error'.
Definition: SemaOpenMP.cpp:11115
clang::OMPDeclareReductionDecl::CopyInit
@ CopyInit
Definition: DeclOpenMP.h:178
clang::ImplicitConversionSequence::isFailure
bool isFailure() const
Definition: Overload.h:655
clang::Sema::ActOnOpenMPTaskgroupDirective
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
Definition: SemaOpenMP.cpp:11162
clang::Sema::ActOnOpenMPAcqRelClause
OMPClause * ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acq_rel' clause.
Definition: SemaOpenMP.cpp:17451
clang::Sema::AllowedExplicit::None
@ None
Allow no explicit functions to be used.
clang::OMPUnifiedAddressClause
This represents 'unified_address' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1171
clang::Sema::startOpenMPLoop
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
Definition: SemaOpenMP.cpp:2490
clang::OMPParallelMaskedDirective::Create
static OMPParallelMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:685
clang::OMPRequiresDecl::Create
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause * > CL)
Create requires node.
Definition: DeclOpenMP.cpp:85
checkNestingOfRegions
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, OpenMPBindClauseKind BindKind, SourceLocation StartLoc)
Definition: SemaOpenMP.cpp:4982
clang::OMPLinearClause::setUpdates
void setUpdates(ArrayRef< Expr * > UL)
Sets the list of update expressions for linear variables.
Definition: OpenMPClause.cpp:563
clang::Sema::BuildCallExpr
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
Definition: SemaExpr.cpp:6881
clang::tooling::X
static ToolExecutorPluginRegistry::Add< AllTUsToolExecutorPlugin > X("all-TUs", "Runs FrontendActions on all TUs in the compilation database. " "Tool results are stored in memory.")
clang::Decl::getAttr
T * getAttr() const
Definition: DeclBase.h:556
clang::OMPUsesAllocatorsClause::Data::AllocatorTraits
Expr * AllocatorTraits
Allocator traits.
Definition: OpenMPClause.h:8386
clang::format::getBase
static Base getBase(const StringRef IntegerLiteral)
Definition: IntegerLiteralSeparatorFixer.cpp:22
llvm::Expected
Definition: LLVM.h:37
clang::CXXScopeSpec
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:65
clang::Sema::FunctionEmissionStatus
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
Definition: Sema.h:4498
clang::Expr::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:234
clang::Sema::ActOnOpenMPThreadsClause
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
Definition: SemaOpenMP.cpp:17471
clang::sema::Capture
Definition: ScopeInfo.h:536
clang::BinaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:3859
clang::Sema::ActOnOpenMPMapClause
OMPClause * ActOnOpenMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'map' clause.
Definition: SemaOpenMP.cpp:22021
clang::DeclarationName::getAsIdentifierInfo
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Definition: DeclarationName.h:419
clang::Sema::StartOpenMPDSABlock
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Definition: SemaOpenMP.cpp:2752
clang::Sema::LookupOMPMapperName
@ LookupOMPMapperName
Look up the name of an OpenMP user-defined mapper.
Definition: Sema.h:4331
clang::ASTContext::getUnsignedPointerDiffType
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
Definition: ASTContext.cpp:6028
clang::DeclContext::getLexicalParent
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition: DeclBase.h:1945
clang::InitializationSequence
Describes the sequence of initializations required to initialize a given object or reference with a s...
Definition: Initialization.h:788
clang::OMPDeclareMapperDecl::Create
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, ArrayRef< OMPClause * > Clauses, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
Definition: DeclOpenMP.cpp:142
clang::NamedDecl::getNameForDiagnostic
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1772
clang::BinaryOperator::isRelationalOp
bool isRelationalOp() const
Definition: Expr.h:3909
clang::Sema::ActOnOpenMPDeclareReductionDirectiveEnd
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
Definition: SemaOpenMP.cpp:22313
clang::Sema::ActOnOpenMPBarrierDirective
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
Definition: SemaOpenMP.cpp:11110
clang::CapturedDecl
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4521
clang::OMPC_BIND_unknown
@ OMPC_BIND_unknown
Definition: OpenMPKinds.h:203
clang::Sema::getCurCapturedRegion
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:2685
clang::Sema::PopDeclContext
void PopDeclContext()
Definition: SemaDecl.cpp:1351
clang::Expr::IgnoreImpCasts
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3016
clang::Expr::EvalResult::Val
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:626
clang::Sema::ActOnOpenMPMaskedTaskLoopSimdDirective
StmtResult ActOnOpenMPMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13577
clang::OMPReleaseClause
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2441
clang::DeclarationName
The name of a declaration.
Definition: DeclarationName.h:144
End
SourceLocation End
Definition: USRLocFinder.cpp:167
checkTypeMappable
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
Definition: SemaOpenMP.cpp:20833
clang::Sema::isInOpenMPAssumeScope
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
Definition: Sema.h:11178
clang::Sema::ActOnOpenMPInteropDirective
StmtResult ActOnOpenMPInteropDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp interop'.
Definition: SemaOpenMP.cpp:17506
clang::Sema::ActOnOpenMPAffinityClause
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
Definition: SemaOpenMP.cpp:23792
clang::ASTContext::getTranslationUnitDecl
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1060
clang::OMPLinearClause::getModifier
OpenMPLinearClauseKind getModifier() const
Return modifier.
Definition: OpenMPClause.h:4047
clang::OpenMPNumTasksClauseModifier
OpenMPNumTasksClauseModifier
Definition: OpenMPKinds.h:212
clang::LookupResult::begin
iterator begin() const
Definition: Lookup.h:335
clang::Sema::ActOnOpenMPParallelMasterTaskLoopDirective
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop' after parsing of the associated statemen...
Definition: SemaOpenMP.cpp:13627
clang::Sema::ActOnOpenMPCopyinClause
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
Definition: SemaOpenMP.cpp:20250
clang::OMPC_GRAINSIZE_unknown
@ OMPC_GRAINSIZE_unknown
Definition: OpenMPKinds.h:209
clang::OMPUsesAllocatorsClause::Create
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
Definition: OpenMPClause.cpp:1601
clang::ArrayType::Normal
@ Normal
Definition: Type.h:3026
clang::OpenMPMapModifierKind
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
Definition: OpenMPKinds.h:78
clang::OMPMasterTaskLoopSimdDirective::Create
static OMPMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1239
clang::Decl::isReferenced
bool isReferenced() const
Whether any declaration of this entity was referenced.
Definition: DeclBase.cpp:482
checkMappableExpressionList
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr * > UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, ArrayRef< OpenMPMapModifierKind > Modifiers=std::nullopt, bool IsMapTypeImplicit=false, bool NoDiagnose=false)
Definition: SemaOpenMP.cpp:21707
clang::Sema::CompoundScopeRAII
A RAII object to enter scope of a compound statement.
Definition: Sema.h:5031
clang::OpenMPSeverityClauseKind
OpenMPSeverityClauseKind
OpenMP attributes for 'severity' clause.
Definition: OpenMPKinds.h:142
clang::Expr::isGLValue
bool isGLValue() const
Definition: Expr.h:275
clang::OMPLoopBasedDirective::HelperExprs::PreCond
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:751
clang::Decl::markUsed
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:472
clang::Declarator::getIdentifierLoc
SourceLocation getIdentifierLoc() const
Definition: DeclSpec.h:2257
findAcceptableDecl
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D)
Definition: SemaOpenMP.cpp:18724
clang::sema::CapturedRegionScopeInfo
Retains information about a captured region.
Definition: ScopeInfo.h:781
clang::Preprocessor::getIdentifierTable
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:1208
buildCapture
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
Definition: SemaOpenMP.cpp:4658
clang::OMPExclusiveClause::Create
static OMPExclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1539
clang::Sema::ActOnOpenMPCollapseClause
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
Definition: SemaOpenMP.cpp:16589
clang::OMPScheduleClause::getSecondScheduleModifierLoc
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Definition: OpenMPClause.h:1788
clang::OMPAlignClause::Create
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
Definition: OpenMPClause.cpp:645
clang::Sema::isInOpenMPDeclareVariantScope
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
Definition: Sema.h:11041
clang::Scope::getParent
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:249
clang::FunctionDecl::isConsteval
bool isConsteval() const
Definition: Decl.h:2379
clang::OpaqueValueExpr
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1147
clang::OMPScheduleClause
This represents 'schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1637
clang::Sema::ActOnOpenMPCriticalDirective
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10825
clang::Sema::Context
ASTContext & Context
Definition: Sema.h:409
clang::OMPInteropInfo
Definition: OpenMPKinds.h:220
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1566
clang::OMPCollapseClause
This represents 'collapse' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:976
clang::CXXRewrittenBinaryOperator::DecomposedForm::Opcode
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition: ExprCXX.h:306
clang::OMPDistributeParallelForDirective::Create
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1573
clang::Type::hasSignedIntegerRepresentation
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2082
clang::ExprError
ExprResult ExprError()
Definition: Ownership.h:278
clang::Sema::ActOnOpenMPCancelDirective
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
Definition: SemaOpenMP.cpp:13319
Decl.h
clang::ConditionalOperator
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4153
clang::NumberOfOMPMapClauseModifiers
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
Definition: OpenMPKinds.h:87
clang::OMPTargetTeamsDistributeParallelForSimdDirective::Create
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2155
clang::OMPTaskwaitDirective::Create
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
Definition: StmtOpenMP.cpp:774
clang::Sema::ActOnOpenMPExecutableDirective
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:6107
clang::CXXScopeSpec::isSet
bool isSet() const
Deprecated.
Definition: DeclSpec.h:211
getRange
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
Definition: SourceCode.cpp:104
clang::Sema::ActOnOpenMPMasterTaskLoopSimdDirective
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13527
clang::ASTContext::typesAreCompatible
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
Definition: ASTContext.cpp:10213
buildDeclRefExpr
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:1549
clang::Sema::ActOnOpenMPDistributeParallelForSimdDirective
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
Definition: SemaOpenMP.cpp:13948
clang::OMPTargetTeamsDistributeSimdDirective::Create
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2216
clang::AttributeCommonInfo::AS_Keyword
@ AS_Keyword
__ptr16, alignas(...), etc.
Definition: AttributeCommonInfo.h:42
clang::ASTContext::BoundMemberTy
CanQualType BoundMemberTy
Definition: ASTContext.h:1106
clang::OMPNocontextClause
This represents 'nocontext' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:8149
clang::Sema::getLangOpts
const LangOptions & getLangOpts() const
Definition: Sema.h:1655
clang::OMPOrderedClause::getNumForLoops
Expr * getNumForLoops() const
Return the number of associated for-loops.
Definition: OpenMPClause.h:1888
clang::Expr::getIntegerConstantExpr
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Definition: ExprConstant.cpp:16019
clang::Sema::ICEConvertDiagnoser
Definition: Sema.h:3915
clang::CorrectionCandidateCallback::clone
virtual std::unique_ptr< CorrectionCandidateCallback > clone()=0
Clone this CorrectionCandidateCallback.
clang::OMPOrderedClause
This represents 'ordered' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1830
clang::Sema::ActOnOpenMPRelaxedClause
OMPClause * ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'relaxed' clause.
Definition: SemaOpenMP.cpp:17466
clang::ASTContext::getTypeAlignInChars
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Definition: ASTContext.cpp:2569
clang::Sema::ActOnOpenMPNontemporalClause
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
Definition: SemaOpenMP.cpp:23521
clang::Declarator::getDeclSpec
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition: DeclSpec.h:1969
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:20
clang::ExprEmpty
ExprResult ExprEmpty()
Definition: Ownership.h:289
clang::CXXRecordDecl::hasMutableFields
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1202
U
clang::Sema::getCurLexicalContext
DeclContext * getCurLexicalContext() const
Definition: Sema.h:13757
clang::OMPAlignedClause::Create
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
Definition: OpenMPClause.cpp:628
buildDeclareReductionRef
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
Definition: SemaOpenMP.cpp:18799
clang::OMPVarListLocTy::StartLoc
SourceLocation StartLoc
Starting location of the clause (the clause keyword).
Definition: OpenMPClause.h:261
clang::OpenMPLastprivateModifier
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
Definition: OpenMPKinds.h:157
clang::Sema::getCurFunctionDecl
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false)
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1457
clang::isOpenMPDistributeDirective
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
Definition: OpenMPKinds.cpp:679
clang::OpenMPBindClauseKind
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
Definition: OpenMPKinds.h:200
clang::isOpenMPLoopTransformationDirective
bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a loop transformation directive.
Definition: OpenMPKinds.cpp:720
clang::OMPThreadPrivateDecl::Create
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
Definition: DeclOpenMP.cpp:28
clang::AttributedStmt
Represents an attribute applied to a statement.
Definition: Stmt.h:1890
clang::OpenMPMotionModifierKind
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
Definition: OpenMPKinds.h:91
clang::Sema::RequireCompleteType
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8722
llvm::MutableArrayRef
Definition: LLVM.h:32
clang::Sema::ActOnOpenMPUseDeviceAddrClause
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
Definition: SemaOpenMP.cpp:23237
checkReductionClauseWithNogroup
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:13336
clang::CapturedStmt::capturesVariable
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1424
clang::ASTContext::getUIntPtrType
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Definition: ASTContext.cpp:6015
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6908
clang::CapturedStmt::getCapturedStmt
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:3645
clang::OMPC_SCHEDULE_MODIFIER_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
Definition: OpenMPKinds.h:39
V
#define V(N, I)
Definition: ASTContext.h:3212
clang::VarDecl::hasInit
bool hasInit() const
Definition: Decl.cpp:2327
clang::IntegerLiteral
Definition: Expr.h:1506
clang::OMPProcBindClause
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1089
clang::PseudoObjectExpr::Create
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
Definition: Expr.cpp:4716
precomputeExpr
static VarDecl * precomputeExpr(Sema &Actions, SmallVectorImpl< Stmt * > &BodyStmts, Expr *E, StringRef Name)
Definition: SemaOpenMP.cpp:5572
clang::Sema::OpenMPVarListDataTy
Data used for processing a list of variables in OpenMP clauses.
Definition: Sema.h:11975
clang::Sema::ActOnOpenMPSIMDClause
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
Definition: SemaOpenMP.cpp:17476
clang::prec::Unknown
@ Unknown
Definition: OperatorPrecedence.h:27
clang::Sema::ActOnOpenMPBeginDeclareVariant
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
Definition: SemaOpenMP.cpp:2683
clang::ASTContext::mergeFunctionTypes
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false, bool AllowCXX=false, bool IsConditionalOperator=false)
Definition: ASTContext.cpp:10271
clang::OMPNovariantsClause
This represents 'novariants' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:8102
min
__DEVICE__ int min(int __a, int __b)
Definition: __clang_cuda_math.h:197
clang::Expr::isTypeDependent
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:187
clang::OMPLoopBasedDirective::HelperExprs::NLB
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
Definition: StmtOpenMP.h:769
clang::OMPLinearClause::Create
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
Definition: OpenMPClause.cpp:582
clang::CallExpr::getDirectCallee
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2983
clang::Sema::ActOnOpenMPSingleExprClause
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:15173
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4823
clang::OMPLoopBasedDirective::HelperExprs::PrivateCounters
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:791
clang::OMPC_LINEAR_unknown
@ OMPC_LINEAR_unknown
Definition: OpenMPKinds.h:66
clang::CompoundStmt
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1418
clang::Sema::ActOnOpenMPCompareClause
OMPClause * ActOnOpenMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'compare' clause.
Definition: SemaOpenMP.cpp:17441
clang::OMPTargetDataDirective::Create
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1004
clang::OMPNumTeamsClause
This represents 'num_teams' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:5998
clang::Sema::CheckOpenMPLinearModifier
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
Definition: SemaOpenMP.cpp:19887
clang::DeclarationName::getCXXOverloadedOperator
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Definition: DeclarationName.h:471
clang::Sema::inTemplateInstantiation
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition: Sema.h:9641
clang::Sema::ActOnCapturedRegionError
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4789
clang::OMPInteropInfo::PreferTypes
llvm::SmallVector< Expr *, 4 > PreferTypes
Definition: OpenMPKinds.h:225
clang::OpenMPLinearClauseKind
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:62
clang::Sema::ActOnOpenMPPartialClause
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
Definition: SemaOpenMP.cpp:16971
clang::OMPCanonicalLoop::create
static OMPCanonicalLoop * create(const ASTContext &Ctx, Stmt *LoopStmt, CapturedStmt *DistanceFunc, CapturedStmt *LoopVarFunc, DeclRefExpr *LoopVarRef)
Create a new OMPCanonicalLoop.
Definition: StmtOpenMP.h:163
clang::OMPSIMDClause
This represents 'simd' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:5052
clang::OMPLoopBasedDirective::HelperExprs::clear
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:825
clang::interp::Opcode
Opcode
Definition: Opcode.h:21
clang::OMPC_NUMTASKS_unknown
@ OMPC_NUMTASKS_unknown
Definition: OpenMPKinds.h:215
clang::Sema::ActOnOpenMPScheduleClause
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
Definition: SemaOpenMP.cpp:17168
clang::OMPDeclareReductionDecl
This represents '#pragma omp declare reduction ...' directive.
Definition: DeclOpenMP.h:171
clang::OMPParallelSectionsDirective::Create
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:701
clang::Sema::ActOnOpenMPTeamsDistributeDirective
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:14172
clang::OMPMasterTaskLoopDirective::Create
static OMPMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1149
clang::PartialDiagnosticAt
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
Definition: PartialDiagnostic.h:205
clang::Declarator::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclSpec.h:2005
clang::OMPSimdDirective::Create
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:301
clang::OMPReverseOffloadClause
This represents 'reverse_offload' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1237
clang::Decl::getAccess
AccessSpecifier getAccess() const
Definition: DeclBase.h:491
clang::QualType::getNonLValueExprType
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3163
StmtOpenMP.h
clang::DeclAccessPair::make
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
Definition: DeclAccessPair.h:35
clang::OMPLinearClause::inits
inits_range inits()
Definition: OpenMPClause.h:4102
clang::DeclRefExpr::Create
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Definition: Expr.cpp:536
clang::Sema::CurFPFeatureOverrides
FPOptionsOverride CurFPFeatureOverrides()
Definition: Sema.h:705
clang::OMPDependClause::Create
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1050
clang::Sema::VarsWithInheritedDSAType
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Definition: Sema.h:11316
clang::Sema::UsesAllocatorsData::RParenLoc
SourceLocation RParenLoc
Definition: Sema.h:12175
clang::Sema::ActOnOpenMPDepobjDirective
StmtResult ActOnOpenMPDepobjDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp depobj'.
Definition: SemaOpenMP.cpp:11217
clang::Sema::ActOnOpenMPPriorityClause
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
Definition: SemaOpenMP.cpp:22540
clang::Decl::specific_attrs
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:542
clang::Sema::ActOnOpenMPToClause
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'to' clause.
Definition: SemaOpenMP.cpp:23078
checkGenericLoopLastprivate
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind K, DSAStackTy *Stack)
Definition: SemaOpenMP.cpp:10515
clang::ConstexprSpecKind::Consteval
@ Consteval
clang::Decl::getKind
Kind getKind() const
Definition: DeclBase.h:435
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3815
clang::Sema::ActOnOpenMPMasterTaskLoopDirective
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13451
clang::OMPClause
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
clang::Decl::setAccess
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:486
widenIterationCount
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
Definition: SemaOpenMP.cpp:9467
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::EUB
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct,...
Definition: StmtOpenMP.h:716
clang::Sema::CreateParsedType
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6574
buildCaptureDecl
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, DeclContext *CurContext, bool AsExpression)
Definition: SemaOpenMP.cpp:4627
Id
int Id
Definition: ASTDiff.cpp:190
clang::VarDecl::isStaticLocal
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1167
clang::OMPOrderedDirective::Create
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:879
checkOpenMPIterationSpace
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
Definition: SemaOpenMP.cpp:9184
hlsl::uint64_t
unsigned long uint64_t
Definition: hlsl_basic_types.h:25
clang::TypeSpecifierSign::Signed
@ Signed
clang::VarDecl::isFunctionOrMethodVarDecl
bool isFunctionOrMethodVarDecl() const
Similar to isLocalVarDecl, but excludes variables declared in blocks.
Definition: Decl.h:1226
clang::Scope
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
clang::OMPLoopBasedDirective::HelperExprs::LastIteration
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:745
clang::Scope::isDeclScope
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
Definition: Scope.h:357
clang::interp::LE
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:628
clang::OpenMPDefaultmapClauseKind
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:110
clang::CXXScopeSpec::isValid
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:198
clang::syntax::NodeRole::Callee
@ Callee
clang::ASTContext::getAsArrayType
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Definition: ASTContext.cpp:6920
clang::Sema::LookupName
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Definition: SemaLookup.cpp:2179
clang::OMPForDirective::Create
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:336
clang::AS_public
@ AS_public
Definition: Specifiers.h:112
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:91
clang::OMPFullClause
Representation of the 'full' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:879
clang::OMPRequiresDecl::clauselists
clauselist_range clauselists()
Definition: DeclOpenMP.h:441
clang::OMPPartialClause::Create
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Definition: OpenMPClause.cpp:982
clang::OMPVarListLocTy::LParenLoc
SourceLocation LParenLoc
Location of '('.
Definition: OpenMPClause.h:263
clang::ASTContext::DependentTy
CanQualType DependentTy
Definition: ASTContext.h:1106
clang::DeclRefExpr::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Expr.cpp:604
clang::Sema::PushDeclContext
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
Definition: SemaDecl.cpp:1344
clang::VarDecl::isStaticDataMember
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1242
clang::Sema::DefaultFunctionArrayConversion
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition: SemaExpr.cpp:506
clang::getOpenMPCaptureRegions
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
Definition: OpenMPKinds.cpp:732
clang::FPOptionsOverride
Represents difference between two FPOptions values.
Definition: LangOptions.h:806
clang::Sema::ActOnOpenMPTargetTeamsDirective
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:14389
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::ASTContext::getSizeType
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Definition: ASTContext.cpp:5977
clang::MemberExpr::CreateImplicit
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
Definition: Expr.h:3233
clang::ExprResult
ActionResult< Expr * > ExprResult
Definition: Ownership.h:262
clang::OMPOrderClause::getKindKwLoc
SourceLocation getKindKwLoc() const
Returns location of clause kind.
Definition: OpenMPClause.h:7786
clang::CPlusPlus
@ CPlusPlus
Definition: LangStandard.h:53
clang::ArrayType
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3019
clang::OMPDistributeParallelForSimdDirective::Create
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1635
clang::Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
Definition: SemaOpenMP.cpp:22446
clang::CapturedDecl::setNothrow
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:5119
clang::OMPCancelDirective::Create
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:818
clang::OMPDetachClause
This represents 'detach' clause in the '#pragma omp task' directive.
Definition: OpenMPClause.h:8195
clang::Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope
void ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, SmallVectorImpl< FunctionDecl * > &Bases)
The declarator D defines a function in the scope S which is nested in an omp begin/end declare varian...
Definition: SemaOpenMP.cpp:7137
clang::Sema::ActOnOpenMPReverseOffloadClause
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
Definition: SemaOpenMP.cpp:17496
clang::OMPTaskLoopSimdDirective::Create
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1106
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7410
clang::OMPTaskReductionClause::Create
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:861
clang::LookupResult::makeFilter
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:708
clang::OpenMPOrderClauseKind
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
Definition: OpenMPKinds.h:164
clang::Decl::isInvalidDecl
bool isInvalidDecl() const
Definition: DeclBase.h:571
buildDistanceFunc
static CapturedStmt * buildDistanceFunc(Sema &Actions, QualType LogicalTy, BinaryOperator::Opcode Rel, Expr *StartExpr, Expr *StopExpr, Expr *StepExpr)
Create a closure that computes the number of iterations of a loop.
Definition: SemaOpenMP.cpp:5595
clang::OMPFirstprivateClause::Create
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:462
clang::OMPDeviceClause
This represents 'device' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:4938
buildPostUpdate
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
Definition: SemaOpenMP.cpp:9517
clang::Sema::ExpressionEvaluationContext::Unevaluated
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
clang::Sema::ActOnOpenMPCancellationPointDirective
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
Definition: SemaOpenMP.cpp:13304
clang::Sema::ActOnOpenMPTargetParallelForSimdDirective
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
Definition: SemaOpenMP.cpp:14061
clang::OMPParallelMaskedTaskLoopDirective::Create
static OMPParallelMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1374
clang::ASTMutationListener
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Definition: ASTMutationListener.h:46
hasClauses
static bool hasClauses(ArrayRef< OMPClause * > Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Definition: SemaOpenMP.cpp:13107
OpenMPKinds.h
clang::OMPParallelMasterTaskLoopDirective::Create
static OMPParallelMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1327
clang::OMPInReductionClause::Create
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:923
clang::OMPPartialClause::getFactor
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
Definition: OpenMPClause.h:946
clang::DeclarationNameInfo::setName
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
Definition: DeclarationName.h:793
clang::OMPVarListLocTy::EndLoc
SourceLocation EndLoc
Ending location of the clause.
Definition: OpenMPClause.h:265
clang::ForStmt
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2578
clang::Sema::ActOnOpenMPAtClause
OMPClause * ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'at' clause.
Definition: SemaOpenMP.cpp:16845
clang::Sema::AddInitializerToDecl
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:13004
clang::Expr::containsErrors
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:240
clang::OMPLoopBasedDirective::HelperExprs::CalcLastIteration
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:749
clang::OMPArraySectionExpr::getBaseOriginalType
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4877
clang::Sema::diagIfOpenMPHostCode
SemaDiagnosticBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
Definition: SemaOpenMP.cpp:2066
clang::OMPParallelForSimdDirective::Create
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:625
clang::OMPSeverityClause::getSeverityKindKwLoc
SourceLocation getSeverityKindKwLoc() const
Returns location of clause kind.
Definition: OpenMPClause.h:1542
clang::Decl::getCanonicalDecl
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:943
clang::Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
Definition: SemaOpenMP.cpp:14577
clang::Sema::ActOnOpenMPDispatchDirective
StmtResult ActOnOpenMPDispatchDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp dispatch' after parsing of the.
Definition: SemaOpenMP.cpp:10465
clang::OMPNowaitClause
This represents 'nowait' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1925
clang::IntegerLiteral::Create
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition: Expr.cpp:983
CastType
CastType
Definition: SemaCast.cpp:46
clang::index::SymbolKind::Field
@ Field
clang::Sema::CreateBuiltinUnaryOp
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
Definition: SemaExpr.cpp:15785
clang::Sema::ActOnOpenMPReadClause
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
Definition: SemaOpenMP.cpp:17421
clang::Sema::PDiag
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
clang::ASTContext::getTypeSize
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2274
clang::Stmt::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:349
clang::ImplicitCastExpr::Create
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition: Expr.cpp:2063
clang::Sema::GetTypeFromParser
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:3107
set
set(LLVM_LINK_COMPONENTS Support) set(LLVM_EXPORTED_SYMBOL_FILE $
Definition: CMakeLists.txt:1
clang::DeclContext::isTranslationUnit
bool isTranslationUnit() const
Definition: DeclBase.h:2004
clang::Sema::getCurLambda
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:2346
clang::Sema::BuildCStyleCastExpr
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:3285
clang::OMPOrderClause::getKind
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:7783
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1307
clang::Sema::ActOnOpenMPTargetTeamsDistributeDirective
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
Definition: SemaOpenMP.cpp:14420
clang::Type::isFunctionType
bool isFunctionType() const
Definition: Type.h:6892
clang::UnresolvedLookupExpr::Create
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.cpp:370
clang::AttributedStmt::Create
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: Stmt.cpp:424
clang::Sema::ActOnOpenMPIteratorVarDecl
void ActOnOpenMPIteratorVarDecl(VarDecl *VD)
Definition: SemaOpenMP.cpp:22461
clang::ImplicitParamDecl
Definition: Decl.h:1657
clang::OMPDynamicAllocatorsClause
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1280
clang::OpenMPClauseKind
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:27
clang::Expr::isInstantiationDependent
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:216
clang::Sema::ActOnOpenMPAtomicDirective
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12411
clang::Sema::CheckCXXThisCapture
bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit=false, bool BuildAndDiagnose=true, const unsigned *const FunctionScopeIndexToStopAt=nullptr, bool ByCopy=false)
Make sure the value of 'this' is actually available in the current context, if it is a potentially ev...
Definition: SemaExprCXX.cpp:1263
clang::OpenMPGrainsizeClauseModifier
OpenMPGrainsizeClauseModifier
Definition: OpenMPKinds.h:206
clang::CR_OpenMP
@ CR_OpenMP
Definition: CapturedStmt.h:19
clang::OMPLoopBasedDirective
The base class for all loop-based directives, including loop transformation directives.
Definition: StmtOpenMP.h:683
clang::Sema::ActOnOpenMPUnrollDirective
StmtResult ActOnOpenMPUnrollDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp unroll' after parsing of its clauses and the associated statement.
Definition: SemaOpenMP.cpp:14894
llvm::SmallString
Definition: LLVM.h:34
clang::Expr::EvalResult
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:624
clang::diff::Update
@ Update
Definition: ASTDiff.h:31
clang::Sema::ActOnOpenMPTeamsDistributeParallelForDirective
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
Definition: SemaOpenMP.cpp:14340
bool
#define bool
Definition: stdbool.h:20
clang::Sema::ActOnOpenMPDeclareMapperType
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
Definition: SemaOpenMP.cpp:22341
clang::Sema::ActOnOpenMPUpdateClause
OMPClause * ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
Definition: SemaOpenMP.cpp:16928
clang::OMPVarListLocTy
This structure contains most locations needed for by an OMPVarListClause.
Definition: OpenMPClause.h:259
clang::OMPSectionDirective::Create
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
Definition: StmtOpenMP.cpp:514
ASTContext.h
clang::interp::Zero
bool Zero(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1357
clang::UnresolvedSet< 8 >
clang::ASTContext::getIntTypeForBitwidth
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
Definition: ASTContext.cpp:12039
clang::Sema::PerformContextualImplicitConversion
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
Definition: SemaOverload.cpp:6193
clang::OpaqueValueExpr::getSourceExpr
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1197
clang::Sema::ActOnOpenMPParallelForSimdDirective
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10926
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:915
clang::OMPArraySectionExpr::getLowerBound
Expr * getLowerBound()
Get lower bound of array section.
Definition: ExprOpenMP.h:94
clang::Scope::isOpenMPLoopScope
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
Definition: Scope.h:491
clang::Sema::ActOnOpenMPXDynCGroupMemClause
OMPClause * ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
Definition: SemaOpenMP.cpp:23848
getListOfPossibleValues
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=std::nullopt)
Definition: SemaOpenMP.cpp:16749
clang::Sema::CapturedParamNameType
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:5156
clang::Sema::ActOnOpenMPAllocatorClause
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
Definition: SemaOpenMP.cpp:16568
clang::Declarator::setFunctionDefinitionKind
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
Definition: DeclSpec.h:2642
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:629
clang::ConstexprSpecKind::Constexpr
@ Constexpr
clang::OMPDeclareMapperDecl
This represents '#pragma omp declare mapper ...' directive.
Definition: DeclOpenMP.h:286
clang::Sema::DefaultFunctionArrayLvalueConversion
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:740
MapTy
llvm::DenseMap< Stmt *, Stmt * > MapTy
Definition: ParentMap.cpp:22
clang::Sema::ActOnOpenMPThreadprivateDirective
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
Definition: SemaOpenMP.cpp:3154
clang::SourceRange::setEnd
void setEnd(SourceLocation e)
Definition: SourceLocation.h:223
clang::TargetInfo::isTLSSupported
bool isTLSSupported() const
Whether the target supports thread-local storage.
Definition: TargetInfo.h:1456
clang::Sema::ActOnOpenMPDynamicAllocatorsClause
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
Definition: SemaOpenMP.cpp:17501
clang::OMPLoopBasedDirective::HelperExprs::PreInits
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:808
clang::NUM_OVERLOADED_OPERATORS
@ NUM_OVERLOADED_OPERATORS
Definition: OperatorKinds.h:26
clang::CapturedStmt
This captures a statement into a function.
Definition: Stmt.h:3544
clang::ASTContext::getCanonicalType
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2500
clang::Sema::isInOpenMPTaskUntiedContext
bool isInOpenMPTaskUntiedContext() const
Return true if currently in OpenMP task with untied clause context.
Definition: SemaOpenMP.cpp:2288
clang::Sema::ActOnOpenMPDefaultClause
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
Definition: SemaOpenMP.cpp:16768
clang::TypeDecl
Represents a declaration of a type.
Definition: Decl.h:3246
llvm::DenseSet
Definition: Sema.h:77
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1783
clang::Expr::EvaluateKnownConstInt
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Definition: ExprConstant.cpp:15469
clang::VarDecl::isLocalVarDecl
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition: Decl.h:1212
clang::Sema::ActOnOpenMPFlushClause
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
Definition: SemaOpenMP.cpp:20456
clang::OMPSingleDirective::Create
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:532
clang::Scope::isOpenMPOrderClauseScope
bool isOpenMPOrderClauseScope() const
Determine whether this scope is some OpenMP directive with order clause which specifies concurrent sc...
Definition: Scope.h:498
clang::DeclContext::isNamespace
bool isNamespace() const
Definition: DeclBase.h:2013
clang::Sema::LookupParsedName
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
Definition: SemaLookup.cpp:2715
clang::Sema::setOpenMPCaptureKind
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
Definition: SemaOpenMP.cpp:2599
clang::Type::isVariablyModifiedType
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: Type.h:2328
clang::Decl::redecls
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:1014
clang::OpaqueValueExpr::setIsUnique
void setIsUnique(bool V)
Definition: Expr.h:1199
clang::Sema::ActOnOpenMPDeclareTargetName
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, DeclareTargetContextInfo &DTCI)
Called on correct id-expression from the '#pragma omp declare target'.
Definition: SemaOpenMP.cpp:22916
clang::CapturedStmt::Capture
Describes the capture of either a variable, or 'this', or variable-length array type.
Definition: Stmt.h:3557
clang::OMPC_MOTION_MODIFIER_unknown
@ OMPC_MOTION_MODIFIER_unknown
Definition: OpenMPKinds.h:95
clang::OMPGrainsizeClause
This represents 'grainsize' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6225
clang::SC_Register
@ SC_Register
Definition: Specifiers.h:245
clang::OMPC_DEVICE_unknown
@ OMPC_DEVICE_unknown
Definition: OpenMPKinds.h:50
clang::CapturedDecl::getParam
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4568
clang::Type::isAnyComplexType
bool isAnyComplexType() const
Definition: Type.h:6994
clang::Sema::ActOnOpenMPInitClause
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
Definition: SemaOpenMP.cpp:17637
clang::OMPLinearClause::setUsedExprs
void setUsedExprs(ArrayRef< Expr * > UE)
Sets the list of used expressions for the linear clause.
Definition: OpenMPClause.cpp:575
clang::Sema::ActOnOpenMPLoopnest
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
Definition: SemaOpenMP.cpp:5953
checkMutuallyExclusiveClauses
static bool checkMutuallyExclusiveClauses(Sema &S, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPClauseKind > MutuallyExclusiveClauses)
Find and diagnose mutually exclusive clause kinds.
Definition: SemaOpenMP.cpp:11056
clang::NestedNameSpecifierLoc
A C++ nested-name-specifier augmented with source location information.
Definition: NestedNameSpecifier.h:243
clang::Redeclarable::getPreviousDecl
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
clang::OMPTargetExitDataDirective::Create
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1032
clang::Sema::TentativeAnalysisScope
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Definition: Sema.h:9772
clang::Stmt::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
Definition: StmtProfile.cpp:2379
clang::Sema::ActOnOpenMPPrivateClause
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
Definition: SemaOpenMP.cpp:17986
clang::Sema::ActOnOpenMPTargetTeamsGenericLoopDirective
StmtResult ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10625
clang::isOpenMPGenericLoopDirective
bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive constitutes a 'loop' directive in the outermost nest.
Definition: OpenMPKinds.cpp:690
Base
clang::Sema::TryImplicitConversion
ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion)
Definition: SemaOverload.cpp:1585
clang::OMPDefaultClause
This represents 'default' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1008
clang::OMPLoopBasedDirective::HelperExprs::Inc
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:757
clang::Sema::ActOnOpenMPDistributeSimdDirective
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:14005
clang::Sema::ActOnOpenMPDeclareReductionDirectiveStart
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
Definition: SemaOpenMP.cpp:22102
clang::Sema::ActOnOpenMPUnifiedAddressClause
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
Definition: SemaOpenMP.cpp:17486
clang::OMPHintClause
This represents 'hint' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6448
clang::Sema::ActOnOpenMPAllocateDirective
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
Definition: SemaOpenMP.cpp:3375
clang::OpenMPDependClauseKind
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition: OpenMPKinds.h:54
getMapClauseKindFromModifier
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
Definition: SemaOpenMP.cpp:3618
clang::Type::isEnumeralType
bool isEnumeralType() const
Definition: Type.h:6990
clang::OMPCriticalDirective
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:2024
clang::Sema::ActOnFinishedOpenMPDeclareTargetContext
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
Definition: SemaOpenMP.cpp:22868
buildCounterUpdate
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
Definition: SemaOpenMP.cpp:9391
clang::Decl::setImplicit
void setImplicit(bool I=true)
Definition: DeclBase.h:577
clang::OMPC_SCHEDULE_unknown
@ OMPC_SCHEDULE_unknown
Definition: OpenMPKinds.h:34
clang::OMPCaptureClause
This represents 'capture' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2236
clang::isOpenMPPrivate
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate',...
Definition: OpenMPKinds.cpp:696
clang::Sema::isVisible
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
Definition: Sema.h:2363
clang::QualType::hasQualifiers
bool hasQualifiers() const
Determine whether this type has any qualifiers.
Definition: Type.h:6723
clang::VarDecl::TLS_None
@ TLS_None
Not a TLS variable.
Definition: Decl.h:935
clang::OMPXDynCGroupMemClause
This represents 'ompx_dyn_cgroup_mem' clause in the '#pragma omp target ...' directive.
Definition: OpenMPClause.h:9013
clang::Expr::IgnoreParenLValueCasts
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:3053
clang::Sema::ActOnOpenMPTileDirective
StmtResult ActOnOpenMPTileDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp tile' after parsing of its clauses and the associated statement.
Definition: SemaOpenMP.cpp:14683
clang::Type::getAsAdjusted
const T * getAsAdjusted() const
Member-template getAsAdjusted<specific type>.
Definition: Type.h:7427
clang::OMPLoopBasedDirective::HelperExprs::DependentInits
SmallVector< Expr *, 4 > DependentInits
List of initializers required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:803
clang::OMPNumTasksClause
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6357
clang::Sema::PerformOpenMPImplicitIntegerConversion
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
Definition: SemaOpenMP.cpp:16325
clang::OMPDeclareReductionDecl::DirectInit
@ DirectInit
Definition: DeclOpenMP.h:177
FinishOpenMPLinearClause
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Definition: SemaOpenMP.cpp:20073
clang::Sema::ActOnOpenMPLinearClause
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
Definition: SemaOpenMP.cpp:19939
clang::Sema::ActOnOpenMPNocontextClause
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
Definition: SemaOpenMP.cpp:17725
clang::OMPBindClause::Create
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
Definition: OpenMPClause.cpp:1663
clang::Sema::getOpenMPCapturedExpr
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
Definition: SemaOpenMP.cpp:17967
checkValueDeclInTarget
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
Definition: SemaOpenMP.cpp:22999
clang::Sema::BuildMemberExpr
MemberExpr * BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs=nullptr)
Definition: SemaExprMember.cpp:895
clang::VarDecl::Create
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:2079
clang::Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective
StmtResult ActOnOpenMPParallelMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop simd' after parsing of the associated sta...
Definition: SemaOpenMP.cpp:13810
clang::CXXScopeSpec::getWithLocInContext
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:152
getVariableCategoryFromDecl
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
Definition: SemaOpenMP.cpp:2094
clang::Decl::isImplicit
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:576
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
clang::MemberExpr::getMemberDecl
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3255
clang::OMPParallelMasterTaskLoopSimdDirective::Create
static OMPParallelMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1422
checkAllocateClauses
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:5436
findOMPAllocatorHandleT
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
Definition: SemaOpenMP.cpp:16513
clang::OMPUnifiedSharedMemoryClause
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1194
clang::ASTContext::Deallocate
void Deallocate(void *Ptr) const
Definition: ASTContext.h:711
clang::Sema::TryCapture_ExplicitByVal
@ TryCapture_ExplicitByVal
Definition: Sema.h:5438
clang::OMPC_MAP_unknown
@ OMPC_MAP_unknown
Definition: OpenMPKinds.h:74
clang::Sema::PopExpressionEvaluationContext
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:17969
clang::FunctionDefinitionKind::Declaration
@ Declaration
clang::Sema::ActOnOpenMPEndDeclareTargetDirective
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
Definition: SemaOpenMP.cpp:22862
clang::OMPMaskedTaskLoopDirective::Create
static OMPMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1194
clang::OMPParallelMasterDirective::Create
static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:669
clang::Sema::ActOnDeclStmt
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:73
clang::OMPSeverityClause::getSeverityKind
OpenMPSeverityClauseKind getSeverityKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:1539
clang::isOpenMPTeamsDirective
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
Definition: OpenMPKinds.cpp:647
clang::DeclRefExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:599
clang::Declarator::SetIdentifier
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
Definition: DeclSpec.h:2260
clang::Sema::LangOpts
const LangOptions & LangOpts
Definition: Sema.h:407
rejectConstNotMutableType
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
Definition: SemaOpenMP.cpp:1703
clang::Sema::ActOnUninitializedDecl
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:13528
checkReductionClauses
static void checkReductionClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Check consistency of the reduction clauses.
Definition: SemaOpenMP.cpp:2775
clang::OMPArraySectionExpr::getLength
Expr * getLength()
Get length of array section.
Definition: ExprOpenMP.h:102
clang::Sema::ConvertDeclToDeclGroup
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition: SemaDecl.cpp:59
clang::OMPArrayShapingExpr
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:146
clang::QualType::getUnqualifiedType
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6728
clang::OMPMergeableClause
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1982
clang::Sema::PerformImplicitConversion
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType.
Definition: SemaOverload.cpp:1602
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::DistCond
Expr * DistCond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct whe...
Definition: StmtOpenMP.h:732
clang::DeclarationNameInfo::getName
DeclarationName getName() const
getName - Returns the embedded declaration name.
Definition: DeclarationName.h:790
getDirectCallExpr
static Expr * getDirectCallExpr(Expr *E)
Definition: SemaOpenMP.cpp:10457
clang::Sema::ActOnOpenMPEndAssumesDirective
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
Definition: SemaOpenMP.cpp:3518
clang::OMPPrivateClause::Create
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:431
clang::Sema::CorrectTypo
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
Definition: SemaLookup.cpp:5375
clang::OMPCriticalDirective::getDirectiveName
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:2079
clang::Sema::ActOnOpenMPFlushDirective
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
Definition: SemaOpenMP.cpp:11178
clang::Type::isFunctionProtoType
bool isFunctionProtoType() const
Definition: Type.h:2149
clang::Type::hasIntegerRepresentation
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
Definition: Type.cpp:1922
buildUserDefinedMapperRef
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
Definition: SemaOpenMP.cpp:21567
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
Definition: SemaOpenMP.cpp:14518
findOMPDependT
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, bool Diagnose=true)
Tries to find omp_depend_t. type.
Definition: SemaOpenMP.cpp:20467
clang::OMPLoopBasedDirective::HelperExprs::EUB
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Definition: StmtOpenMP.h:767
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
Definition: SemaOpenMP.cpp:14463
DiagnosticSema.h
clang::OpaquePtr
Wrapper for void* pointer.
Definition: Ownership.h:50
clang::OMPUnrollDirective::Create
static OMPUnrollDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp unroll'.
Definition: StmtOpenMP.cpp:429
clang::TargetInfo::isVLASupported
bool isVLASupported() const
Whether target supports variable-length arrays.
Definition: TargetInfo.h:1467
clang::OMPCopyinClause::Create
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:674
clang::getOpenMPSimpleClauseTypeName
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
Definition: OpenMPKinds.cpp:242
clang::Sema::ActOnOpenMPHasDeviceAddrClause
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
Definition: SemaOpenMP.cpp:23372
clang::sema::FunctionScopeInfo
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:102
clang::Sema::ActOnOpenMPDeclareMapperDirective
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
Definition: SemaOpenMP.cpp:22357
clang::VK_LValue
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:127
clang::Sema::MarkDeclarationsReferencedInExpr
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=std::nullopt)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:20144
clang::Sema::diagnoseTypo
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
Definition: SemaLookup.cpp:5672
clang::Type::isArithmeticType
bool isArithmeticType() const
Definition: Type.cpp:2176
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7477
clang::OMPOrderClause
This represents 'order' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:7716
checkArrayExpressionDoesNotReferToUnitySize
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Definition: SemaOpenMP.cpp:20905
clang::OMPMasterDirective::Create
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:549
clang::OMPSafelenClause
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:720
clang::getOpenMPVariantManglingSeparatorStr
static constexpr StringRef getOpenMPVariantManglingSeparatorStr()
OpenMP variants are mangled early based on their OpenMP context selector.
Definition: Decl.h:4885
clang::OMPC_ORDER_MODIFIER_last
@ OMPC_ORDER_MODIFIER_last
Definition: OpenMPKinds.h:175
clang::Sema::ActOnOpenMPParallelSectionsDirective
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:11016
clang::OMPForSimdDirective::Create
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:451
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3041
clang::Sema::ActOnOpenMPParallelMaskedTaskLoopDirective
StmtResult ActOnOpenMPParallelMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop' after parsing of the associated statemen...
Definition: SemaOpenMP.cpp:13684
clang::OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_DEFAULTMAP_MODIFIER_unknown
Definition: OpenMPKinds.h:119
clang::AccessSpecifier
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:111
clang::OMPSimdlenClause::getSimdlen
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:776
clang::Decl::getSourceRange
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:420
clang::OMPParallelMaskedTaskLoopSimdDirective::Create
static OMPParallelMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1469
clang::OMPLoopBasedDirective::HelperExprs::PrevUB
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:777
clang::OMPScheduleClause::getFirstScheduleModifier
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:1767
getOpenMPCaptureRegionForClause
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
Definition: SemaOpenMP.cpp:15317
clang::OMPTaskyieldDirective::Create
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:736
clang::MemberExpr::getBase
Expr * getBase() const
Definition: Expr.h:3249
clang::InitializationSequence::Perform
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Definition: SemaInit.cpp:8292
clang::OMPC_DEFAULTMAP_MODIFIER_last
@ OMPC_DEFAULTMAP_MODIFIER_last
Definition: OpenMPKinds.h:123
clang::OMPDependClause::DependDataTy
Definition: OpenMPClause.h:4792
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::OMPUntiedClause
This represents 'untied' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1942
clang::CallExpr::Create
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1478
clang::OMPAtClause::getAtKind
OpenMPAtClauseKind getAtKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:1459
clang::OMPRelaxedClause
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
Definition: OpenMPClause.h:2482
clang::OMPClauseWithPreInit
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc.
Definition: OpenMPClause.h:195
clang::VarDecl::isThisDeclarationADefinition
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2189
clang::MemberExpr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:3367
clang::CR_Default
@ CR_Default
Definition: CapturedStmt.h:17
clang::OO_None
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
clang::OMPDependClause
This represents implicit clause 'depend' for the '#pragma omp task' directive.
Definition: OpenMPClause.h:4784
clang::Type::isUnionType
bool isUnionType() const
Definition: Type.cpp:599
clang::DeclStmt::getSingleDecl
const Decl * getSingleDecl() const
Definition: Stmt.h:1326
clang::Sema::DeclGroupPtrTy
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Sema.h:400
clang::Declarator::getCXXScopeSpec
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
Definition: DeclSpec.h:1984
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
processImplicitMapsWithDefaultMappers
static void processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, SmallVectorImpl< OMPClause * > &Clauses)
Perform DFS through the structure/class data members trying to find member(s) with user-defined 'defa...
Definition: SemaOpenMP.cpp:5976
clang::Sema::CTK_ErrorRecovery
@ CTK_ErrorRecovery
Definition: Sema.h:4526
clang::VarDecl::getAnyInitializer
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition: Decl.h:1317
clang::Type::isDependentType
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2310
clang::Type::isInstantiationDependentType
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2318
clang::VK_PRValue
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:123
clang::Sema::isOpenMPDeclareMapperVarDeclAllowed
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const
Definition: SemaOpenMP.cpp:22466
clang::OMPSizesClause
This represents the 'sizes' clause in the '#pragma omp tile' directive.
Definition: OpenMPClause.h:786
clang::OMPExecutableDirective::getDirectiveKind
OpenMPDirectiveKind getDirectiveKind() const
Definition: StmtOpenMP.h:556
clang::QualType::isTriviallyCopyableType
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition: Type.cpp:2506
clang::Sema::getCurBlock
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:2303
clang::Sema::ActOnOpenMPSectionDirective
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10444
clang::OMPAllocateClause::classof
static bool classof(const OMPClause *T)
Definition: OpenMPClause.h:515
clang::Sema::ActOnOpenMPUsesAllocatorClause
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
Definition: SemaOpenMP.cpp:23658
clang::Sema::IsDerivedFrom
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
Definition: SemaDeclCXX.cpp:2880
clang::LookupResult::suppressDiagnostics
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:609
clang::ASTContext::VoidPtrTy
CanQualType VoidPtrTy
Definition: ASTContext.h:1105
clang::LookupResult::empty
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:339
clang::Sema::FullExprArg::get
Expr * get() const
Definition: Sema.h:4988
clang::Sema::PushExpressionEvaluationContext
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
Definition: SemaExpr.cpp:17676
clang::FieldDecl::isBitField
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3021
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6896
clang::Sema::ActOnOpenMPInclusiveClause
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
Definition: SemaOpenMP.cpp:23560
clang::Sema::UsesAllocatorsData::AllocatorTraits
Expr * AllocatorTraits
Allocator traits.
Definition: Sema.h:12173
clang::Sema::diagIfOpenMPDeviceCode
SemaDiagnosticBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
Definition: SemaOpenMP.cpp:2028
clang::Decl::hasAttrs
bool hasAttrs() const
Definition: DeclBase.h:502
getOrderedNumberExpr
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:10238
clang::Sema::ActOnFinishFullExpr
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:6874
clang::syntax::NodeRole::Size
@ Size
clang::OMPOrderedClause::children
child_range children()
Definition: OpenMPClause.h:1901
false
#define false
Definition: stdbool.h:22
clang::OMPSizesClause::getNumSizes
unsigned getNumSizes() const
Returns the number of list items.
Definition: OpenMPClause.h:828
clang::OMPC_SEVERITY_unknown
@ OMPC_SEVERITY_unknown
Definition: OpenMPKinds.h:145
clang::OMPC_SCHEDULE_MODIFIER_last
@ OMPC_SCHEDULE_MODIFIER_last
Definition: OpenMPKinds.h:43
clang::DeclResult
ActionResult< Decl * > DeclResult
Definition: Ownership.h:268
clang::Stmt::IgnoreContainers
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top,...
Definition: Stmt.cpp:196
clang::ASTContext::getDeclAlign
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
Definition: ASTContext.cpp:1783
clang::OMPCopyprivateClause::Create
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:715
clang::Sema::isInOpenMPDeclareTargetContext
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
Definition: Sema.h:11277
clang::ActionResult::get
PtrTy get() const
Definition: Ownership.h:169
clang::isOpenMPTaskLoopDirective
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
Definition: OpenMPKinds.cpp:594
clang::Sema::ActOnOpenMPAcquireClause
OMPClause * ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acquire' clause.
Definition: SemaOpenMP.cpp:17456
clang::LCK_ByRef
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
clang::Sema::MakeFullExpr
FullExprArg MakeFullExpr(Expr *Arg)
Definition: Sema.h:5004
clang::ClassTemplateDecl
Declaration of a class template.
Definition: DeclTemplate.h:2270
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:703
clang::ComplexType
Complex values, per C99 6.2.5p11.
Definition: Type.h:2723
clang::OMPArraySectionExpr::getBase
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
Definition: ExprOpenMP.h:85
clang::Scope::getBreakParent
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
Definition: Scope.h:284
clang::VarDecl::getStorageClass
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1127
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3864
clang::Sema::UsesAllocatorsData
Data for list of allocators.
Definition: Sema.h:12169
clang::OMPErrorDirective::Create
static OMPErrorDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Definition: StmtOpenMP.cpp:747
clang::OMPSectionsDirective::Create
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:494
clang::Sema::ActOnOpenMPTaskyieldDirective
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
Definition: SemaOpenMP.cpp:11105
clang::OMPTargetUpdateDirective::Create
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1558
clang::VarDecl::isLocalVarDeclOrParm
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Definition: Decl.h:1221
clang::DeclContext::addDecl
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1607
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4023
clang::OMPCapturedExprDecl
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:383
clang::ASTContext::Idents
IdentifierTable & Idents
Definition: ASTContext.h:631
clang::OMPLoopBasedDirective::HelperExprs
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:741
clang::Sema::ActOnOpenMPSingleExprWithArgClause
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:17000
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1929
clang::Expr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:330
clang::OMPArrayShapingExpr::getBase
Expr * getBase()
Fetches base expression of array shaping expression.
Definition: ExprOpenMP.h:214
clang::QualType::isConstant
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:876
clang::RecordDecl::fields
field_range fields() const
Definition: Decl.h:4223
clang::sema::CapturedRegionScopeInfo::TheCapturedDecl
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Definition: ScopeInfo.h:784
clang::Sema::isInOpenMPTargetExecutionDirective
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
Definition: SemaOpenMP.cpp:2293
TypeOrdering.h
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
Begin
SourceLocation Begin
Definition: USRLocFinder.cpp:165
clang::Sema::Private
@ Private
The private module fragment, between 'module :private;' and the end of the translation unit.
Definition: Sema.h:1945
llvm::ArrayRef
Definition: LLVM.h:31
clang::Sema::AR_inaccessible
@ AR_inaccessible
Definition: Sema.h:7852
Value
Value
Definition: UninitializedValues.cpp:102
clang::OpenMPDefaultmapClauseModifier
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:118
clang::OMPFilterClause
This represents 'filter' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:8601
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::OMPNontemporalClause::Create
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1496
clang::Sema::PopFunctionScopeInfo
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
Definition: Sema.cpp:2234
Scope.h
clang::OMPUsesAllocatorsClause::Data
Data for list of allocators.
Definition: OpenMPClause.h:8382
clang::EnterExpressionEvaluationContext
RAII object that enters a new expression evaluation context.
Definition: Sema.h:13916
OpenMPClause.h
clang::Expr::IgnoreParenImpCasts
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3036
clang::Sema::ActOnOpenMPLoopInitialization
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
Definition: SemaOpenMP.cpp:9098
clang::CanQual::withConst
QualType withConst() const
Retrieves a version of this type with const applied.
Definition: CanonicalType.h:161
clang::DeclGroupRef
Definition: DeclGroup.h:51
clang::Sema::ActOnOpenMPTeamsDirective
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13282
clang::FloatingLiteral::Create
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:1084
clang::CapturedStmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.h:3736
clang::Sema::ActOnOpenMPTeamsDistributeSimdDirective
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:14217
clang::OMPTeamsDistributeParallelForSimdDirective::Create
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1908
clang::Sema::ActOnOpenMPOrderClause
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
Definition: SemaOpenMP.cpp:16889
clang::OpenMPAtomicDefaultMemOrderClauseKind
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
Definition: OpenMPKinds.h:127
clang::OMPNogroupClause
This represents 'nogroup' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6315
clang::ArraySubscriptExpr
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2657
clang::Sema::DefaultLvalueConversion
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:630
clang::Sema::EndOpenMPDSABlock
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Definition: SemaOpenMP.cpp:2850
clang::Sema::ActOnOpenMPDependClause
OMPClause * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Definition: SemaOpenMP.cpp:20512
clang::Sema::ActOnOpenMPLastprivateClause
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
Definition: SemaOpenMP.cpp:18419
ASTMutationListener.h
clang::CapturedStmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
Definition: Stmt.h:3744
clang::Sema::ActOnOpenMPReductionClause
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'reduction' clause.
Definition: SemaOpenMP.cpp:19803
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:358
clang::OMPLoopBasedDirective::HelperExprs::Finals
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:797
clang::SD_Static
@ SD_Static
Static storage duration.
Definition: Specifiers.h:315
clang::ActionResult::isInvalid
bool isInvalid() const
Definition: Ownership.h:165
StmtVisitor.h
clang::OMPClause::getBeginLoc
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:71
clang::VarDecl::setInitStyle
void setInitStyle(InitializationStyle Style)
Definition: Decl.h:1404
clang::Sema::CheckExtraCXXDefaultArguments
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
Definition: SemaDeclCXX.cpp:407
getRelatedCompoundReductionOp
static BinaryOperatorKind getRelatedCompoundReductionOp(BinaryOperatorKind BOK)
Definition: SemaOpenMP.cpp:19077
clang::DeclContext::isExternCXXContext
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1240
clang::OMPTaskgroupDirective::Create
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:788
clang::Sema::ActOnConditionalOp
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:9358
clang::Sema::ActOnOpenMPTargetEnterDataDirective
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13170
clang::Sema::ActOnOpenMPDistScheduleClause
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
Definition: SemaOpenMP.cpp:22704
clang::BinaryOperator::getOperatorLoc
SourceLocation getOperatorLoc() const
Definition: Expr.h:3856
reportOriginalDsa
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
Definition: SemaOpenMP.cpp:3560
clang::OMPLoopBasedDirective::HelperExprs::Updates
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:795
clang::Sema::ActOnOpenMPIsDevicePtrClause
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
Definition: SemaOpenMP.cpp:23289
clang::Type::getAsRecordDecl
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1787
clang::isOpenMPNestingDistributeDirective
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
Definition: OpenMPKinds.cpp:672
clang::Declarator::isInvalidType
bool isInvalidType() const
Definition: DeclSpec.h:2627
clang::Sema::ActOnOpenMPCall
ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig)
Given the potential call expression Call, determine if there is a specialization via the OpenMP decla...
Definition: SemaOpenMP.cpp:7248
clang::Sema::ActOnOpenMPOrderedDirective
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:11269
clang::Sema::isOpenMPPrivateDecl
OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, unsigned CapLevel) const
Check if the specified variable is used in 'private' clause.
Definition: SemaOpenMP.cpp:2504
clang::Sema::AA_Initializing
@ AA_Initializing
Definition: Sema.h:3712
clang::OMPCapturedExprDecl::Create
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:174
clang::OMPSimdlenClause
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:755
clang::OMPTargetTeamsDirective::Create
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2029
clang::OMPMaskedTaskLoopSimdDirective::Create
static OMPMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1283
clang::DeclContext::Encloses
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1244
clang::Sema::PushOnScopeChains
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
Definition: SemaDecl.cpp:1537
clang::DeclSpec::getConstexprSpecifier
ConstexprSpecKind getConstexprSpecifier() const
Definition: DeclSpec.h:777
clang::Redeclarable::getMostRecentDecl
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
clang::DeclContext::isFileContext
bool isFileContext() const
Definition: DeclBase.h:1999
clang::Type::isOverloadableType
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:7333
clang::Sema::startOpenMPCXXRangeFor
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
Definition: SemaOpenMP.cpp:2496
clang::Sema::ActOnOpenMPUseDevicePtrClause
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
Definition: SemaOpenMP.cpp:23152
clang::BinaryOperatorKind
BinaryOperatorKind
Definition: OperationKinds.h:25
clang::Sema::LookupSingleName
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
Definition: SemaLookup.cpp:3289
clang::CXXRewrittenBinaryOperator::DecomposedForm::RHS
const Expr * RHS
The original right-hand side.
Definition: ExprCXX.h:310
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1327
clang::Sema::ActOnOpenMPProcBindClause
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
Definition: SemaOpenMP.cpp:16802
clang::ExprValueKind
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:120
clang::OMPParallelGenericLoopDirective::Create
static OMPParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2443
clang::Expr::isValueDependent
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:170
clang::Sema::ActOnOpenMPMergeableClause
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Definition: SemaOpenMP.cpp:17416
clang::ConstStmtVisitor
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:193
clang::Sema::ActOnOpenMPMaskedDirective
StmtResult ActOnOpenMPMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp masked' after parsing of the.
Definition: SemaOpenMP.cpp:10813
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::Sema::areMultiversionVariantFunctionsCompatible
bool areMultiversionVariantFunctionsCompatible(const FunctionDecl *OldFD, const FunctionDecl *NewFD, const PartialDiagnostic &NoProtoDiagID, const PartialDiagnosticAt &NoteCausedDiagIDAt, const PartialDiagnosticAt &NoSupportDiagIDAt, const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, bool ConstexprSupported, bool CLinkageMayDiffer)
Checks if the variant/multiversion functions are compatible.
Definition: SemaDecl.cpp:10959
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::NLB
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e....
Definition: StmtOpenMP.h:726
clang::Sema::ActOnOpenMPAlignClause
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
Definition: SemaOpenMP.cpp:16989
clang::Expr::EvaluateAsInt
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Definition: ExprConstant.cpp:15231
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:744
clang::OpaquePtr::make
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:60
Priority
int Priority
Definition: Format.cpp:2777
clang::Sema::ActOnOpenMPAlignedClause
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
Definition: SemaOpenMP.cpp:20176
clang::BinaryOperator::getOverloadedOpcode
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2132
clang::OMPExecutableDirective
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
clang::Sema::AA_Converting
@ AA_Converting
Definition: Sema.h:3711
clang::OMPWriteClause
This represents 'write' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2061
clang::Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D)
Act on D, a function definition inside of an omp [begin/end] assumes.
Definition: SemaOpenMP.cpp:7113
clang::DeclarationNameTable::getIdentifier
DeclarationName getIdentifier(const IdentifierInfo *ID)
Create a declaration name that is a simple identifier.
Definition: DeclarationName.h:622
clang::OMPHasDeviceAddrClause::Create
static OMPHasDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1450
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
clang::Sema::tryCaptureOpenMPLambdas
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
Definition: SemaOpenMP.cpp:4721
clang::Type::isStructureOrClassType
bool isStructureOrClassType() const
Definition: Type.cpp:585
clang::OMPMaskedDirective::Create
static OMPMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:2295
clang::ASTContext::getLValueReferenceType
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Definition: ASTContext.cpp:3510
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::DeclStmt
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1311
clang::Sema::SemaDiagnosticBuilder
A generic diagnostic builder for errors which may or may not be deferred.
Definition: Sema.h:1770
clang::Sema::ActOnOpenMPFirstprivateClause
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
Definition: SemaOpenMP.cpp:18132
clang::InitializationKind
Describes the kind of initialization being performed, along with location information for tokens rela...
Definition: Initialization.h:566
clang::ActionResult< Expr * >
clang::OMPLoopBasedDirective::HelperExprs::NumIterations
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:747
clang::isOpenMPLoopBoundSharingDirective
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
Definition: OpenMPKinds.cpp:711
clang::Sema::ActOnOpenMPTargetParallelDirective
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13021
clang::VarDecl::isUsableInConstantExpressions
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
Definition: Decl.cpp:2429
clang::OMPFlushClause
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
Definition: OpenMPClause.h:4624
clang::OMPAtClause::getAtKindKwLoc
SourceLocation getAtKindKwLoc() const
Returns location of clause kind.
Definition: OpenMPClause.h:1462
clang::CXXThisExpr
Represents the this expression in C++.
Definition: ExprCXX.h:1148
clang::UnresolvedSetImpl::end
iterator end()
Definition: UnresolvedSet.h:84
clang::OMPMapClause::Create
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1135
clang::Sema::targetDiag
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD=nullptr)
Definition: Sema.cpp:1861
clang::Sema::tryCaptureVariable
bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
Definition: SemaExpr.cpp:19036
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::LB
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:710
clang::isOpenMPWorksharingDirective
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
Definition: OpenMPKinds.cpp:579
ScopeInfo.h
clang::Sema::ActOnOpenMPTeamsGenericLoopDirective
StmtResult ActOnOpenMPTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10576
clang::Sema::ActOnOpenMPCanonicalLoop
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
Definition: SemaOpenMP.cpp:5805
clang::OMPTeamsDistributeParallelForDirective::Create
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1968
clang::isOpenMPTaskingDirective
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop,...
Definition: OpenMPKinds.cpp:707
checkMapConflicts
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
Definition: SemaOpenMP.cpp:21319
clang::OMPAtomicDirective::Create
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expressions Exprs)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
Definition: StmtOpenMP.cpp:898
clang::Sema::finalizeOpenMPDelayedAnalysis
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, const FunctionDecl *Callee, SourceLocation Loc)
Finishes analysis of the deferred functions calls that may be declared as host/nohost during device/h...
Definition: SemaOpenMP.cpp:2695
clang::Sema::ActOnOpenMPTargetExitDataDirective
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13207
clang::Sema::ActOnOpenMPBindClause
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
Definition: SemaOpenMP.cpp:23831
clang::IdentifierInfo::setMangledOpenMPVariantName
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
Definition: IdentifierTable.h:443
clang::Scope::OpenMPOrderClauseScope
@ OpenMPOrderClauseScope
This is a scope of some OpenMP directive with order clause which specifies concurrent.
Definition: Scope.h:147
clang::StmtResult
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:263
clang::Type::hasUnsignedIntegerRepresentation
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
Definition: Type.cpp:2132
clang::Sema::getCurScope
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:13746
clang::VarDecl::CInit
@ CInit
C-style initialization with assignment.
Definition: Decl.h:920
clang::Sema::DiagnoseUnterminatedOpenMPDeclareTarget
void DiagnoseUnterminatedOpenMPDeclareTarget()
Report unterminated 'omp declare target' or 'omp begin declare target' at the end of a compilation un...
Definition: SemaOpenMP.cpp:22874
clang::Sema::ActOnOpenMPSimdDirective
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10291
clang::Sema::ActOnOpenMPInReductionClause
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'in_reduction' clause.
Definition: SemaOpenMP.cpp:19867
buildPreInits
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl * > PreInits)
Build preinits statement for the given declarations.
Definition: SemaOpenMP.cpp:9493
clang::Sema::isDeclInScope
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
Definition: SemaDecl.cpp:1595
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:196
clang::Sema::AA_Casting
@ AA_Casting
Definition: Sema.h:3714
findOMPEventHandleT
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_event_handle_t type.
Definition: SemaOpenMP.cpp:22642
clang::FunctionProtoType::ExtProtoInfo
Extra information about a function prototype.
Definition: Type.h:4106
clang::SourceLocation::isInvalid
bool isInvalid() const
Definition: SourceLocation.h:111
clang::Sema::ActOnOpenMPNumTeamsClause
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
Definition: SemaOpenMP.cpp:22486
clang::OMPTargetParallelGenericLoopDirective::Create
static OMPTargetParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2487
clang::UnaryOperator::getSubExpr
Expr * getSubExpr() const
Definition: Expr.h:2222
clang::OMPUseClause
This represents the 'use' clause in '#pragma omp ...' directives.
Definition: OpenMPClause.h:7940
clang::OMPTeamsDistributeSimdDirective::Create
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1864
clang::OMPArraySectionExpr
OpenMP 5.0 [2.1.5, Array Sections].
Definition: ExprOpenMP.h:56
clang::Expr::IgnoreParens
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3032
PartialDiagnostic.h
clang::Sema::getOpenMPDeclareMapperVarName
const ValueDecl * getOpenMPDeclareMapperVarName() const
Definition: SemaOpenMP.cpp:22481
clang::Sema::EndOpenMPClause
void EndOpenMPClause()
End analysis of clauses.
Definition: SemaOpenMP.cpp:2764
clang
Definition: CalledOnceCheck.h:17
clang::Sema::PushFunctionScope
void PushFunctionScope()
Enter a new function scope.
Definition: Sema.cpp:2117
clang::Type::isAnyPointerType
bool isAnyPointerType() const
Definition: Type.h:6900
clang::sema::FunctionScopeInfo::CompoundScopes
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:219
clang::DeclarationNameInfo::getAsString
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
Definition: DeclarationName.cpp:453
clang::OMPAcquireClause
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2400
isOpenMPDeviceDelayedContext
static bool isOpenMPDeviceDelayedContext(Sema &S)
Definition: SemaOpenMP.cpp:2013
clang::DeclarationNameInfo::setLoc
void setLoc(SourceLocation L)
setLoc - Sets the main location of the declaration name.
Definition: DeclarationName.h:799
clang::OMPLoopBasedDirective::HelperExprs::PrevLB
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:774
clang::OMPC_MAP_MODIFIER_unknown
@ OMPC_MAP_MODIFIER_unknown
Definition: OpenMPKinds.h:79
clang::VarDecl::DeclarationOnly
@ DeclarationOnly
This declaration is only a declaration.
Definition: Decl.h:1254
Kind2Unsigned
Definition: SemaOpenMP.cpp:5266
clang::Type::isArrayType
bool isArrayType() const
Definition: Type.h:6962
clang::sema::CapturedRegionScopeInfo::OpenMPCaptureLevel
unsigned short OpenMPCaptureLevel
Definition: ScopeInfo.h:799
clang::Sema::ActOnOpenMPNumTasksClause
OMPClause * ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
Definition: SemaOpenMP.cpp:22594
clang::OMPMessageClause::getMessageString
Expr * getMessageString() const
Returns message string of the clause.
Definition: OpenMPClause.h:1607
clang::OMPLoopBasedDirective::HelperExprs::Init
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:755
distance
float __ovld __cnfn distance(float, float)
Returns the distance between p0 and p1.
clang::OpenMPDistScheduleClauseKind
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:103
clang::UnresolvedSetImpl::addDecl
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:91
clang::Sema::VerifyICEDiagnoser
Abstract base class used for diagnosing integer constant expression violations.
Definition: Sema.h:12892
clang::OMPTargetTeamsDistributeDirective::Create
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2044
clang::Sema::ActOnOpenMPForSimdDirective
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10366
clang::OMPAffinityClause::Create
static OMPAffinityClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Creates clause with a modifier a list of locator items.
Definition: OpenMPClause.cpp:1622
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:72
clang::QualType::withConst
QualType withConst() const
Definition: Type.h:915
clang::Sema::ActOnOpenMPFinalClause
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
Definition: SemaOpenMP.cpp:16294
clang::ComparisonCategoryType::Last
@ Last
clang::VarDecl::isConstexpr
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1521
clang::UnaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:2217
clang::OMPC_DIST_SCHEDULE_unknown
@ OMPC_DIST_SCHEDULE_unknown
Definition: OpenMPKinds.h:106
clang::OMPIsDevicePtrClause::Create
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1403
clang::BinaryOperator::getRHS
Expr * getRHS() const
Definition: Expr.h:3866
clang::OMPBarrierDirective::Create
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:762
clang::OMPTraitInfo::getAsVariantMatchInfo
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
Definition: OpenMPClause.cpp:2467
clang::OMPTargetTeamsDistributeParallelForDirective::Create
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2091
clang::Expr::SE_AllowSideEffects
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Definition: Expr.h:653
buildCounterInit
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
Definition: SemaOpenMP.cpp:9367
clang::OMPInitClause::Create
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
Definition: OpenMPClause.cpp:1640
clang::Sema::ActOnOpenMPParallelGenericLoopDirective
StmtResult ActOnOpenMPParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10674
clang::OMPBindClause
This represents 'bind' clause in the '#pragma omp ...' directives.
Definition: OpenMPClause.h:8642
clang::Sema::isOpenMPCapturedByRef
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
Definition: SemaOpenMP.cpp:2107
clang::Declarator
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1834
clang::OMPTargetParallelDirective::Create
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:939
clang::OMPVarListClause::varlists
varlist_range varlists()
Definition: OpenMPClause.h:319
clang::DeclaratorContext::Condition
@ Condition
clang::OMPAcqRelClause
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2359
clang::Sema::ActOnOpenMPMasterDirective
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10802
clang::OpenMPScheduleClauseModifier
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:38
clang::Sema::ActOnOpenMPSeqCstClause
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
Definition: SemaOpenMP.cpp:17446
clang::Expr::isIntegerConstantExpr
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Definition: ExprConstant.cpp:16000
clang::OMPTeamsDistributeDirective::Create
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1820
clang::prec::Level
Level
Definition: OperatorPrecedence.h:26
clang::OMPTraitInfo::anyScoreOrCondition
bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)
Definition: OpenMPClause.h:8801
clang::LookupResult::Filter
A class for iterating through a result set and possibly filtering out results.
Definition: Lookup.h:643
clang::TypoCorrection::getCorrectionDecl
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Definition: TypoCorrection.h:151
clang::Sema::ActOnOpenMPClause
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:17257
clang::Sema::StartOpenMPClause
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Definition: SemaOpenMP.cpp:2760
clang::Sema::isCompleteType
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition: Sema.h:2478
clang::Sema::ActOnOpenMPTargetUpdateDirective
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
Definition: SemaOpenMP.cpp:13243
clang::Expr::getType
QualType getType() const
Definition: Expr.h:143
getCollapseNumberExpr
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:10230
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::CorrectionCandidateCallback
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
Definition: TypoCorrection.h:281
clang::OMPDeclareReductionDecl::Create
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:112
clang::QualType::withRestrict
QualType withRestrict() const
Definition: Type.h:931
clang::CXXRecordDecl::hasDefinition
bool hasDefinition() const
Definition: DeclCXX.h:555
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6606
clang::Sema::ActOnIntegerConstant
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3682
clang::BinaryOperator::getOverloadedOperator
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2170
clang::Sema::CheckOpenMPLinearDecl
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type, bool IsDeclareSimd=false)
Checks that the specified declaration matches requirements for the linear decls.
Definition: SemaOpenMP.cpp:19897
clang::NamedDecl::getDeclName
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
clang::Sema::ActOnOpenMPEndDeclareVariant
void ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
Definition: SemaOpenMP.cpp:2688
clang::Sema::ActOnOpenMPDeclareReductionInitializerEnd
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
Definition: SemaOpenMP.cpp:22292
clang::OMPRequiresDecl
This represents '#pragma omp requires...' directive.
Definition: DeclOpenMP.h:416
clang::Sema::lookupOpenMPDeclareTargetName
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
Definition: SemaOpenMP.cpp:22882
clang::Sema::checkOpenMPDeclareVariantFunction
std::optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
Definition: SemaOpenMP.cpp:7362
checkOMPArraySectionConstantForReduction
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
Definition: SemaOpenMP.cpp:19010
clang::DeclContext::isDependentContext
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1174
clang::Sema::ActOnOpenMPDistributeParallelForDirective
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
Definition: SemaOpenMP.cpp:13904
clang::Sema::ActOnParenExpr
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4164
clang::Sema::CheckOMPThreadPrivateDecl
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
Definition: SemaOpenMP.cpp:3194
unsigned
clang::Sema::IgnoredValueConversions
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
Definition: SemaExprCXX.cpp:8144
clang::SC_Auto
@ SC_Auto
Definition: Specifiers.h:244
clang::OMPDistributeSimdDirective::Create
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1694
clang::OMPC_ORDER_unknown
@ OMPC_ORDER_unknown
Definition: OpenMPKinds.h:167
clang::OMPTaskDirective::Create
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:720
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:337
clang::OMPLoopBasedDirective::HelperExprs::builtAll
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:815
Expected
llvm::Expected< T > Expected
Definition: EvalEmitter.cpp:20
clang::Sema::ActOnOpenMPTaskwaitDirective
StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
Definition: SemaOpenMP.cpp:11146
clang::LCK_This
@ LCK_This
Capturing the *this object by reference.
Definition: Lambda.h:34
clang::OMPAllocateDecl::Create
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL, ArrayRef< OMPClause * > CL)
Definition: DeclOpenMP.cpp:57
clang::Sema::ActOnOpenMPTaskLoopDirective
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13363
clang::OMPReductionClause::Create
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > CopyOps, ArrayRef< Expr * > CopyArrayTemps, ArrayRef< Expr * > CopyArrayElems, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:788
clang::InitializedEntity
Describes an entity that is being initialized.
Definition: Initialization.h:47
clang::Sema::ActOnOpenMPHintClause
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
Definition: SemaOpenMP.cpp:22627
clang::QualType::getTypePtrOrNull
const Type * getTypePtrOrNull() const
Definition: Type.h:6639
clang::Sema::ActOnCapturedRegionStart
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:4701
clang::InitializedEntity::InitializeVariable
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
Definition: Initialization.h:248
clang::Decl::getAttrs
AttrVec & getAttrs()
Definition: DeclBase.h:508
clang::LookupResult::getFoundDecl
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:543
clang::OMPLoopBasedDirective::HelperExprs::NUB
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
Definition: StmtOpenMP.h:771
clang::LookupResult::getAsSingle
DeclClass * getAsSingle() const
Definition: Lookup.h:533
clang::Sema::getTypeName
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
Definition: SemaDecl.cpp:328
clang::OMPGenericLoopDirective::Create
static OMPGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2312
clang::Sema::ActOnOpenMPSingleDirective
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10771
clang::VerifyDiagnosticConsumer::Directive
Directive - Abstract class representing a parsed verify directive.
Definition: VerifyDiagnosticConsumer.h:191
clang::Sema::BuildUnaryOp
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
Definition: SemaExpr.cpp:16057
clang::DeclContextLookupResult
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1334
clang::OpaquePtr::getAsOpaquePtr
void * getAsOpaquePtr() const
Definition: Ownership.h:90
clang::ArraySubscriptExpr::getBase
Expr * getBase()
Definition: Expr.h:2694
checkSimdlenSafelenSpecified
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:10246
clang::Sema::CreateBuiltinArraySubscriptExpr
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
Definition: SemaExpr.cpp:5646
clang::Sema::ActOnOpenMPNumThreadsClause
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
Definition: SemaOpenMP.cpp:16411
clang::OMPLinearClause::getCalcStep
Expr * getCalcStep()
Returns expression to calculate linear step.
Definition: OpenMPClause.h:4068
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3172
clang::OMPThreadLimitClause
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6074
clang::CXXBasePaths
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Definition: CXXInheritance.h:117
clang::ASTContext::getTrivialTypeSourceInfo
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
Definition: ASTContext.cpp:3075
clang::OMPLoopBasedDirective::HelperExprs::ST
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:765
clang::OMPVarListClause::getLParenLoc
SourceLocation getLParenLoc() const
Returns the location of '('.
Definition: OpenMPClause.h:335
clang::Sema::ActOnOpenMPSimdlenClause
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
Definition: SemaOpenMP.cpp:16499
clang::OMPTargetParallelForSimdDirective::Create
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1738
clang::OMPUseDeviceAddrClause::Create
static OMPUseDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1356
clang::QualType::getTypePtr
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6635
clang::OMPReadClause
This represents 'read' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2022
clang::OpenMPDirectiveKind
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:24
clang::ASTContext::getPointerType
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Definition: ASTContext.cpp:3386
clang::CanonicalDeclPtr
A wrapper class around a pointer that always points to its canonical declaration.
Definition: Redeclarable.h:349
Parent
NodeId Parent
Definition: ASTDiff.cpp:191
clang::ReferenceType
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2887
clang::Expr::Classification
The return type of classify().
Definition: Expr.h:325
clang::Sema::AllowFold
@ AllowFold
Definition: Sema.h:12908
clang::DeclContext::isExternCContext
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1225
clang::Sema::MarkVariableReferenced
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
Definition: SemaExpr.cpp:19931
clang::Sema::ActOnOpenMPParallelMaskedDirective
StmtResult ActOnOpenMPParallelMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel masked' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10993
clang::OMPClauseWithPostUpdate::get
static OMPClauseWithPostUpdate * get(OMPClause *C)
Definition: OpenMPClause.cpp:181
clang::Sema::ActOnOpenMPDeclareReductionCombinerEnd
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
Definition: SemaOpenMP.cpp:22231
clang::isOpenMPTargetExecutionDirective
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
Definition: OpenMPKinds.cpp:623
clang::Decl::setInvalidDecl
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
clang::OMPUseDevicePtrClause::Create
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< Expr * > PrivateVars, ArrayRef< Expr * > Inits, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1306
clang::Sema::ActOnOpenMPAssumesDirective
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
Definition: SemaOpenMP.cpp:3466
clang::Sema::ActOnOpenMPTaskDirective
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:11078
clang::ASTContext::hasSameType
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2516
clang::Sema::LookupOrdinaryName
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:4288
clang::OMPClause::getEndLoc
SourceLocation getEndLoc() const
Returns the ending location of the clause.
Definition: OpenMPClause.h:74
clang::Sema::ActOnOpenMPDeclareSimdDirective
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
Definition: SemaOpenMP.cpp:6839
clang::OMPInclusiveClause::Create
static OMPInclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1521
llvm::SmallVectorImpl
Definition: Randstruct.h:18
clang::Sema::getOpenMPCaptureLevels
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
Definition: SemaOpenMP.cpp:4621
clang::VarDecl::getInitStyle
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition: Decl.h:1418
clang::Sema::ActOnOpenMPUntiedClause
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
Definition: SemaOpenMP.cpp:17410
clang::OMPScanDirective::Create
static OMPScanDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:864
clang::LookupResult::isVisible
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
Definition: SemaLookup.cpp:2074
clang::Sema::HandleDeclarator
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
Definition: SemaDecl.cpp:6225
clang::OMPNumThreadsClause
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:674
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:714
clang::SC_None
@ SC_None
Definition: Specifiers.h:238
clang::Sema::ActOnCompoundStmt
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
Definition: SemaStmt.cpp:409
true
#define true
Definition: stdbool.h:21
clang::OMPLoopBasedDirective::HelperExprs::UB
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:763
clang::Sema::ActOnOpenMPDeviceClause
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
Definition: SemaOpenMP.cpp:20778
clang::Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop simd' after parsing of the associated sta...
Definition: SemaOpenMP.cpp:13741
clang::DeclarationName::isEmpty
bool isEmpty() const
Evaluates true when this declaration name is empty.
Definition: DeclarationName.h:381
clang::Sema::ActOnOpenMPAtomicDefaultMemOrderClause
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
Definition: SemaOpenMP.cpp:16830
clang::Type::isIntegerType
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7236
clang::Sema::ActOnOpenMPDeclareVariantDirective
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPInteropInfo > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.
Definition: SemaOpenMP.cpp:7665
clang::Sema::getPrintingPolicy
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:3255
buildLoopVarFunc
static CapturedStmt * buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, QualType LogicalTy, DeclRefExpr *StartExpr, Expr *Step, bool Deref)
Create a closure that computes the loop variable from the logical iteration number.
Definition: SemaOpenMP.cpp:5742
clang::ASTContext::hasSameUnqualifiedType
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2543
llvm::SmallSetVector
Definition: ExternalSemaSource.h:23
clang::Sema::ActOnOpenMPTargetDataDirective
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13139
clang::ArrayType::getElementType
QualType getElementType() const
Definition: Type.h:3040
clang::Expr
This represents one expression.
Definition: Expr.h:111
clang::Sema::FindAssociatedClassesAndNamespaces
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr * > Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
Definition: SemaLookup.cpp:3244
clang::FieldDecl::getCanonicalDecl
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition: Decl.h:3146
clang::VarDecl::isDirectInit
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1423
clang::OpenMPScheduleClauseKind
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:30
clang::Sema::ActOnOpenMPDeclareReductionInitializerStart
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Definition: SemaOpenMP.cpp:22245
clang::Type::isSpecificBuiltinType
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7173
getExprAsWritten
static const Expr * getExprAsWritten(const Expr *E)
Definition: SemaOpenMP.cpp:1231
clang::OMPC_DEFAULTMAP_unknown
@ OMPC_DEFAULTMAP_unknown
Definition: OpenMPKinds.h:114
clang::CapturedStmt::getCapturedDecl
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1400
findOMPAlloctraitT
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_alloctrait_t type.
Definition: SemaOpenMP.cpp:23644
clang::ParmVarDecl::Create
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2834
clang::OMPFullClause::Create
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
Definition: OpenMPClause.cpp:969
clang::OMPTileDirective::Create
static OMPTileDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, unsigned NumLoops, Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp tile'.
Definition: StmtOpenMP.cpp:408
clang::VarDecl::hasLocalStorage
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1143
clang::OMPParallelForDirective::Create
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:580
clang::OMPFlushClause::Create
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1018
clang::Sema::LookupOMPReductionName
@ LookupOMPReductionName
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:4329
clang::OMPTargetEnterDataDirective::Create
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1018
clang::Sema::getCurrentThisType
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Definition: SemaExprCXX.cpp:1191
clang::QualType::addConst
void addConst()
Add the const type qualifier to this QualType.
Definition: Type.h:912
isValidInteropVariable
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, SourceLocation VarLoc, OpenMPClauseKind Kind)
Definition: SemaOpenMP.cpp:17579
clang::OMPLoopBasedDirective::HelperExprs::DistCombinedFields
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
Definition: StmtOpenMP.h:811
clang::Sema::PP
Preprocessor & PP
Definition: Sema.h:408
clang::CXXScopeSpec::getBeginLoc
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:74
clang::OMPToClause::Create
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1192
clang::DeclarationNameInfo::getLoc
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Definition: DeclarationName.h:796
getPrivateItem
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false, StringRef DiagType="")
Definition: SemaOpenMP.cpp:5345
clang::Sema::ActOnOpenMPTaskLoopSimdDirective
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13401
clang::DeclarationNameInfo
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Definition: DeclarationName.h:767
clang::Type::isIncompleteType
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2258
clang::CastExpr
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3483
clang::ASTContext::getConstantArrayType
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
Definition: ASTContext.cpp:3618
clang::InitializationKind::CreateCopy
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Definition: Initialization.h:673
clang::Sema::ActOnOpenMPTargetParallelForDirective
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13052
clang::ASTContext::DeclMustBeEmitted
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
Definition: ASTContext.cpp:11773
clang::FunctionDecl::parameters
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2584
clang::sema::CapturedRegionScopeInfo::OpenMPLevel
unsigned short OpenMPLevel
Definition: ScopeInfo.h:798
clang::Sema::ActOnOpenMPUnifiedSharedMemoryClause
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
Definition: SemaOpenMP.cpp:17491
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
clang::format::Base
Base
Definition: IntegerLiteralSeparatorFixer.cpp:20
clang::OMPSizesClause::Create
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
Definition: OpenMPClause.cpp:950
clang::Decl::setReferenced
void setReferenced(bool R=true)
Definition: DeclBase.h:606
clang::Decl::addAttr
void addAttr(Attr *A)
Definition: DeclBase.cpp:903
clang::UnresolvedSetImpl::append
void append(iterator I, iterator E)
Definition: UnresolvedSet.h:129
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1079
clang::Decl::isCanonicalDecl
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:949
clang::OMPLoopBasedDirective::HelperExprs::Cond
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:753
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1235
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1917
clang::OMPFinalClause
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:628
clang::OMPLoopBasedDirective::doForAllLoops
static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, llvm::function_ref< bool(unsigned, Stmt *)> Callback, llvm::function_ref< void(OMPLoopTransformationDirective *)> OnTransformationCallback)
Calls the specified callback function for all the loops in CurStmt, from the outermost to the innermo...
Definition: StmtOpenMP.cpp:125
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3996
clang::Sema::ActOnOpenMPUseClause
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
Definition: SemaOpenMP.cpp:17662
clang::DeclContext::Equals
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition: DeclBase.h:2053
checkOpenMPLoop
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopBasedDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
Definition: SemaOpenMP.cpp:9540
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2813
clang::OMPSafelenClause::getSafelen
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:741
fitsInto
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
Definition: SemaOpenMP.cpp:9483
clang::CXXOperatorCallExpr
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
clang::DeclarationNameInfo::getBeginLoc
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
Definition: DeclarationName.h:869
StmtCXX.h
clang::OMPTargetTeamsGenericLoopDirective::Create
static OMPTargetTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2398
clang::Sema::ActOnOpenMPThreadLimitClause
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
Definition: SemaOpenMP.cpp:22513
clang::Sema::CheckBooleanCondition
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
Definition: SemaExpr.cpp:20359
clang::ActionResult::isUsable
bool isUsable() const
Definition: Ownership.h:166
isConstNotMutableType
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
Definition: SemaOpenMP.cpp:1684
clang::Sema::ActOnOpenMPSectionsDirective
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10405
clang::Sema::setFunctionHasBranchProtectedScope
void setFunctionHasBranchProtectedScope()
Definition: Sema.cpp:2288
clang::isOpenMPSimdDirective
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
Definition: OpenMPKinds.cpp:656
clang::LookupResult::getRepresentativeDecl
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:550
handleDeclareVariantConstructTrait
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, OpenMPDirectiveKind DKind, bool ScopeEntry)
Definition: SemaOpenMP.cpp:4154
clang::Sema::ActOnOpenMPReleaseClause
OMPClause * ActOnOpenMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'release' clause.
Definition: SemaOpenMP.cpp:17461
clang::specific_attr_iterator
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:33
clang::Sema::ActOnOpenMPSizesClause
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
Definition: SemaOpenMP.cpp:16950
clang::OMPMessageClause
This represents 'message' clause in the '#pragma omp error' directive.
Definition: OpenMPClause.h:1571
clang::Sema::ActOnOpenMPParallelMasterDirective
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel master' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10970
applyOMPAllocateAttribute
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, Expr *Alignment, SourceRange SR)
Definition: SemaOpenMP.cpp:3351
clang::OMPClauseWithPreInit::get
static OMPClauseWithPreInit * get(OMPClause *C)
Definition: OpenMPClause.cpp:59
clang::ASTContext::getVariableArrayType
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type.
Definition: ASTContext.cpp:3815
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::Sema::CheckBaseClassAccess
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
Definition: SemaAccess.cpp:1863
clang::ASTContext::getMemberPointerType
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
Definition: ASTContext.cpp:3588
clang::VarDecl::CallInit
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:923
clang::UnresolvedSetImpl::begin
iterator begin()
Definition: UnresolvedSet.h:83
clang::Sema::ActOnOpenMPParallelForDirective
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10882
clang::ValueDecl::setType
void setType(QualType newType)
Definition: Decl.h:715
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::NUB
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e....
Definition: StmtOpenMP.h:729
clang::StmtError
StmtResult StmtError()
Definition: Ownership.h:279
Initialization.h
clang::Sema::ActOnOpenMPSharedClause
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
Definition: SemaOpenMP.cpp:18603
Kind2Unsigned::operator()
unsigned operator()(argument_type DK)
Definition: SemaOpenMP.cpp:5268
clang::OpenMPOrderClauseModifier
OpenMPOrderClauseModifier
OpenMP modifiers for 'order' clause.
Definition: OpenMPKinds.h:171
clang::CXXScopeSpec::isInvalid
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:196
Kind2Unsigned::argument_type
OpenMPDirectiveKind argument_type
Definition: SemaOpenMP.cpp:5267
clang::Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
Definition: SemaOpenMP.cpp:14278
clang::ImplicitConversionSequence
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
Definition: Overload.h:517
clang::LookupResult::isAmbiguous
bool isAmbiguous() const
Definition: Lookup.h:301
clang::TargetOMPContext
Clang specific specialization of the OMPContext to lookup target features.
Definition: OpenMPClause.h:8848
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:441
clang::OMPArraySectionExpr::getColonLocFirst
SourceLocation getColonLocFirst() const
Definition: ExprOpenMP.h:118
clang::Sema::ActOnOpenMPRegionStart
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
Definition: SemaOpenMP.cpp:4171
clang::Sema::ExpressionEvaluationContext::PotentiallyEvaluated
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
clang::Sema::ActOnOpenMPNowaitClause
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
Definition: SemaOpenMP.cpp:17404
clang::Sema::ActOnOpenMPAllocateClause
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
Definition: SemaOpenMP.cpp:23458
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
checkArrayExpressionDoesNotReferToWholeSize
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
Definition: SemaOpenMP.cpp:20847